简体   繁体   中英

WCF: Occasional rejection of client credentials

We are currently migrating services of an old WCF application to servers in a new domain. Since the migration the below mentioned error occurs from time to time.

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...).

The difficult thing is that all calls work 95% of the time and there is no transparent reason a call suddenly fails.

The configurations and calls look like this:

Caller:

<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();

Recipient:

<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();
}

The implementation is registered via castle.

container.Register(Component.For<IWcfInterface>().ImplementedBy<WcfClass>().LifeStyle.PerWcfOperation());

on the old Servers .NET 4.7 is installed, 4.8 on the new ones.

Suspecting that the credentials are somewhere lost on the way from Caller to Recipient I contacted the Network Team but they told me that this is not possible.

I would like to see which credentials arrive at the service. If this is not possible I also would be content with any other solution.

This is largely due to a Windows Domain mismatch and there are two solutions:

  1. Put both the application server and the client on the same Windows Domain.

  2. If the machines are in the same domain, verify that the user account used to run the service is a domain account and not a local server account.

Note that if you use windows authentication, the client domain and server must be in the same windows domain.

Another solution is not to use windows authentication:

<bindings>
  <netTcpBinding>
    <binding name="TcpBinding">
      <security mode="None"></security>
    </binding>
  </netTcpBinding>
</bindings>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM