WCF:偶尔拒绝客户端凭据
WCF: Occasional rejection of client credentials
我们目前正在将旧 WCF 应用程序的服务迁移到新域中的服务器。自迁移以来,不时出现以下错误。
An exception has occurred...
Exception Details: The server has rejected the client credentials.
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The server has rejected the client credentials. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.ServiceModel.Security.SecurityNegotiationException: The server has rejected the client credentials.
System.Security.Authentication.InvalidCredentialException: The server has rejected the client credentials.
System.ComponentModel.Win32Exception: The logon attempt failed
--- End of inner ExceptionDetail stack trace ---
at System.Net.Security.NegoState.ProcessReceivedBlob(Byte[] message, LazyAsyncResult lazyResult)
at System.Net.Security.NegoState.StartSendBlob(Byte[] message, LazyAsyncResult lazyResult)
at System.Net.Security.NegoState.StartSendBlob(Byte[] message, LazyAsyncResult lazyResult)
at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
at...).
困难的是所有调用在 95% 的时间都有效,并且没有明确的调用突然失败的原因。
配置和调用如下所示:
来电者:
<binding name="Binding_ServiceTCP"
closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="infinite" sendTimeout="infinite"
transferMode="Buffered" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
<readerQuotas maxDepth="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" />
</binding>
<Channel ChannelType="IWcfInterface" Name="ServiceName"
Binding="Binding_ServiceTCP" Address="net.tcp://serverinnewdomain:59886/Service" Identity="" />
objectOfIWcfInterfaceImplementingClass.WcfCall();
收件人:
<service behaviorConfiguration="BehaviourName" name="ServiceName">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="Binding_ServiceTCP" contract="IWcfInterface" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://serverinnewdomain:59886/Service" />
</baseAddresses>
</host>
</service>
<behavior name="BehaviourName">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
<binding name="Binding_ServiceTCP"
closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="infinite" sendTimeout="infinite"
transferMode="Buffered" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
<readerQuotas maxDepth="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" />
</binding>
[ServiceContract(Namespace = "http://some.cool/namespace")]
[XmlSerializerFormat]
public interface IWcfInterface
{
[OperationContract]
[XmlSerializerFormat(SupportFaults = true)]
SomeClass WcfCall();
}
实现是通过城堡注册的。
container.Register(Component.For<IWcfInterface>().ImplementedBy<WcfClass>().LifeStyle.PerWcfOperation());
在旧服务器上安装 .NET 4.7,在新服务器上安装 4.8。
我怀疑凭据在从呼叫者到接收者的途中丢失了某个地方,我联系了网络团队,但他们告诉我这是不可能的。
我想看看哪些凭据到达了服务。如果这是不可能的,我也会对任何其他解决方案感到满意。
这主要是由于 Windows 域不匹配,有两种解决方案:
将应用服务器和客户端放在同一个 Windows 域中。
如果机器在同一个域中,请验证用于运行服务的用户帐户是域帐户而不是本地服务器帐户。
注意,如果使用windows认证,客户端域和服务器必须在同一个windows域中。
另一种解决方案是不使用 windows 身份验证:
<bindings>
<netTcpBinding>
<binding name="TcpBinding">
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
我们目前正在将旧 WCF 应用程序的服务迁移到新域中的服务器。自迁移以来,不时出现以下错误。
An exception has occurred...
Exception Details: The server has rejected the client credentials.
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The server has rejected the client credentials. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.ServiceModel.Security.SecurityNegotiationException: The server has rejected the client credentials.
System.Security.Authentication.InvalidCredentialException: The server has rejected the client credentials.
System.ComponentModel.Win32Exception: The logon attempt failed --- End of inner ExceptionDetail stack trace ---
at System.Net.Security.NegoState.ProcessReceivedBlob(Byte[] message, LazyAsyncResult lazyResult)
at System.Net.Security.NegoState.StartSendBlob(Byte[] message, LazyAsyncResult lazyResult)
at System.Net.Security.NegoState.StartSendBlob(Byte[] message, LazyAsyncResult lazyResult)
at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
at...).
困难的是所有调用在 95% 的时间都有效,并且没有明确的调用突然失败的原因。
配置和调用如下所示:
来电者:
<binding name="Binding_ServiceTCP"
closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="infinite" sendTimeout="infinite"
transferMode="Buffered" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
<readerQuotas maxDepth="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" />
</binding>
<Channel ChannelType="IWcfInterface" Name="ServiceName"
Binding="Binding_ServiceTCP" Address="net.tcp://serverinnewdomain:59886/Service" Identity="" />
objectOfIWcfInterfaceImplementingClass.WcfCall();
收件人:
<service behaviorConfiguration="BehaviourName" name="ServiceName">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="Binding_ServiceTCP" contract="IWcfInterface" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://serverinnewdomain:59886/Service" />
</baseAddresses>
</host>
</service>
<behavior name="BehaviourName">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
<binding name="Binding_ServiceTCP"
closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="infinite" sendTimeout="infinite"
transferMode="Buffered" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
<readerQuotas maxDepth="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" />
</binding>
[ServiceContract(Namespace = "http://some.cool/namespace")]
[XmlSerializerFormat]
public interface IWcfInterface
{
[OperationContract]
[XmlSerializerFormat(SupportFaults = true)]
SomeClass WcfCall();
}
实现是通过城堡注册的。
container.Register(Component.For<IWcfInterface>().ImplementedBy<WcfClass>().LifeStyle.PerWcfOperation());
在旧服务器上安装 .NET 4.7,在新服务器上安装 4.8。
我怀疑凭据在从呼叫者到接收者的途中丢失了某个地方,我联系了网络团队,但他们告诉我这是不可能的。
我想看看哪些凭据到达了服务。如果这是不可能的,我也会对任何其他解决方案感到满意。
这主要是由于 Windows 域不匹配,有两种解决方案:
将应用服务器和客户端放在同一个 Windows 域中。
如果机器在同一个域中,请验证用于运行服务的用户帐户是域帐户而不是本地服务器帐户。
注意,如果使用windows认证,客户端域和服务器必须在同一个windows域中。
另一种解决方案是不使用 windows 身份验证:
<bindings>
<netTcpBinding>
<binding name="TcpBinding">
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>