17
votes

While calling a web service I get the following error:

The HTTP request is unauthorized with client authentication scheme 'NTLM'. The authentication header received from the server was 'NTLM'. The HTTP request is unauthorized with client authentication scheme 'NTLM'. The authentication header received from the server was 'NTLM'.

I have a Silverlight 4 application that calls a WCF web service, both on my IIS (7). my WCF web service calls another ASMX web service, installed on a different web server, using NTLM (Windows Authentication). Both servers, mine and the one hosting the ASMX web service are in the same domain.

When the Silverlight client opens the application from the server using http://localhost/MySiteName everything works fine. But when the Silverlight client opens the application from a different client, which is not the server but still in the same domain, using http://MyServerName/MySiteName then I get the error.

Windows Authentication is enabled in my IIS. Anonymous Authentication is disabled in my IIS.

Binding configuration for calling my WCF web service is:

    <binding name="winAuthBasicHttpBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" />
      </security>
    </binding>

Binding configuration for calling the ASMX web service is:

    <binding name="ClNtlmBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Ntlm" />
      </security>
    </binding>
7
Binding configuration for calling my WCF web service is: <binding name="winAuthBasicHttpBinding"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows" /> </security> </binding> Binding configuration for calling the ASMX web service is: <binding name="ClNtlmBinding"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Ntlm" /> </security> </binding>kruvi

7 Answers

20
votes

OK, here are the things that come into mind:

  • Your WCF service presumably running on IIS must be running under the security context that has the privilege that calls the Web Service. You need to make sure in the app pool with a user that is a domain user - ideally a dedicated user.
  • You can not use impersonation to use user's security token to pass back to ASMX using impersonation since my WCF web service calls another ASMX web service, installed on a **different** web server
  • Try changing Ntlm to Windows and test again.

OK, a few words on impersonation. Basically it is a known issue that you cannot use the impersonation tokens that you got to one server, to pass to another server. The reason seems to be that the token is a kind of a hash using user's password and valid for the machine generated from so it cannot be used from the middle server.


UPDATE

Delegation is possible under WCF (i.e. forwarding impersonation from a server to another server). Look at this topic here.

8
votes

It's a long time since the question was posted, but I experienced the same issue in a similar scenario. I have a console application and I was consuming a web service and our IIS server where the webservice was placed has windows authentication (NTLM) enabled.

I followed this link and that fixed my problem. Here's the sample code for App.config:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="Service1Soap">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Ntlm" proxyCredentialType="None"
                        realm=""/>
                    <message clientCredentialType="UserName" algorithmSuite="Default"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost/servicename/service1.asmx" 
            binding="basicHttpBinding" bindingConfiguration="ListsSoap"/>
    </client>
</system.serviceModel>
5
votes

For me the solution was besides using "Ntlm" as credential type, similar as Jeroen K's solution. If I had the permission level I would plus on his post, but let me post my whole code here, which will support both Windows and other credential types like basic auth:

    XxxSoapClient xxxClient = new XxxSoapClient();
    ApplyCredentials(userName, password, xxxClient.ClientCredentials);

    private static void ApplyCredentials(string userName, string password, ClientCredentials clientCredentials)
    {
        clientCredentials.UserName.UserName = userName;
        clientCredentials.UserName.Password = password;
        clientCredentials.Windows.ClientCredential.UserName = userName;
        clientCredentials.Windows.ClientCredential.Password = password;
        clientCredentials.Windows.AllowNtlm = true;
        clientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
    }  
4
votes

I had to move domain, username, password from

client.ClientCredentials.UserName.UserName = domain + "\\" + username; client.ClientCredentials.UserName.Password = password

to

client.ClientCredentials.Windows.ClientCredential.UserName = username; client.ClientCredentials.Windows.ClientCredential.Password = password; client.ClientCredentials.Windows.ClientCredential.Domain = domain;

0
votes

1) I had to do the following with my configuration: (Add BackConnectionHostNames or Disable Loopback Check) http://support.microsoft.com/kb/896861

2) I was working off a dev system on an isolated dev network. I had gotten it working using the dev system's computer name in the URL to the web service, but when I modified the URL to the URL that would be used in production (rather than the computer name), I started getting the NTLM error.

3) I noticed the security log showed that the service account failing to login with an error similar to the one in the MSDN article.

4) Adding the BackConnectionHostNames made it so I could log into the server via a browser running on the server, but the service account still had NTLM errors when trying to authenticate for the web services. I wound up disabling the loop back check and that fixed it for me.

0
votes

Maybe you can refer to : http://msdn.microsoft.com/en-us/library/ms731364.aspx My solution is to change 2 properties authenticationScheme and proxyAuthenticationScheme to "Ntlm", and then it works.

PS: My environment is as follow - Server side: .net 2.0 ASMX - Client side: .net 4

0
votes

My problem was; None admin users were getting "the http request is unauthorized with client authentication scheme 'negotiate' asmx" on my asmx services.

I gived read/execute folder permissions for the none admin users and my problem was solved.