windows-authenticationwshttpbindingtransport-security

wsHttpbinding with TransportWithMessageCredential and windows authentication


I have an IIS hosted WCF service with the following binding configuration (I removed all the attributes from the binding for space) for wsHttpBinding and TransportWithMessageCredential

   <wsHttpBinding>
    <binding name="BindingName" .../>
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
  </wsHttpBinding>   

with a service behaviour of:

  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <serviceCredentials>
       <userNameAuthentication userNamePasswordValidationMode="Windows" />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>

Anonymous authentication is disabled and windows authentication enabled.

On the client side the Credentials are being set using a valid windows user and password but i get the following exception on every call to the service:

The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'. ---> System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.

With a self hosted version of the WCF service it works fine running under a valid windows account.

Any help is appreciated.


Solution

  • Enabling Windows authentication in IIS requires that the credentials are supplied on the transport layer whereas your configuration defines that authentication happens at the message layer

    To fix this problem you need to do one of the following

    1) enable anonymous access in IIS as authentication will be handled at the message layer

    or

    2) update your security mode to be transport

    <wsHttpBinding>
        <binding name="BindingName" .../>
          <security mode="Transport">
            <transport clientCredentialType="Ntlm" />
          </security>
        </binding>
      </wsHttpBinding>