40
votes

Few days ago I had quite a headache with authentication problems when using Windows authentication between client and wcf web service. The error I was getting was "The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was "NTLM". None of the solutions on stack worked because most of them were related to old methods.

6
Seems similar to the problem I have now. Could you post the image again? Thanks.kerzek
What do you mean "post image again", you do not see the image in the post?VidasV
Sorry, it was a proxy thing...kerzek
postimg.org/image/iriadkxit here is the linkVidasV
You should probaply add your own answer as an answer and accept it so people can vote for it :).Jos Vinke

6 Answers

27
votes

THE ANSWER: The problem was all of the posts for such an issue were related to older kerberos and IIS issues where proxy credentials or AllowNTLM properties were helping. My case was different. What I have discovered after hours of picking worms from the ground was that somewhat IIS installation did not include Negotiate provider under IIS Windows authentication providers list. So I had to add it and move up. My WCF service started to authenticate as expected. Here is the screenshot how it should look if you are using Windows authentication with Anonymous auth OFF.

You need to right click on Windows authentication and choose providers menu item.

enter image description here

Hope this helps to save some time.

8
votes

I have upgraded my older version of WCF to WCF 4 with below changes, hope you can also make the similar changes.

1. Web.config:

<system.serviceModel>
      <bindings>
        <basicHttpBinding>
          <binding name="Demo_BasicHttp">
            <security mode="TransportCredentialOnly">
              <transport clientCredentialType="InheritedFromHost"/>
            </security>
          </binding>
        </basicHttpBinding>
      </bindings>
      <services>
        <service name="DemoServices.CalculatorService.ServiceImplementation.CalculatorService" behaviorConfiguration="Demo_ServiceBehavior">
          <endpoint address="" binding="basicHttpBinding"
              bindingConfiguration="Demo_BasicHttp" contract="DemoServices.CalculatorService.ServiceContracts.ICalculatorServiceContract">
            <identity>
              <dns value="localhost"/>
            </identity>
          </endpoint>
          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="Demo_ServiceBehavior">
            <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
            <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
            <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
            <serviceDebug includeExceptionDetailInFaults="false"/>
          </behavior>
        </serviceBehaviors>
      </behaviors>
      <protocolMapping>
        <add scheme="http" binding="basicHttpBinding" bindingConfiguration="Demo_BasicHttp"/>
      </protocolMapping>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    </system.serviceModel>

2. App.config:

    <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_ICalculatorServiceContract" maxBufferSize="2147483647" maxBufferPoolSize="33554432" maxReceivedMessageSize="2147483647" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00">
          <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="4096" />
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:24357/CalculatorService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICalculatorServiceContract" contract="ICalculatorServiceContract" name="Demo_BasicHttp" />
    </client>
  </system.serviceModel>
4
votes

For me the solution was besides using "Ntlm" as credential type:

    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;
    }  
2
votes

Not this exact problem, but this is the top result when googling for almost the exact same error:

If you see this problem calling a WCF Service hosted on the same machine, you may need to populate the BackConnectionHostNames registry key

  1. In regedit, locate and then click the following registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
  2. Right-click MSV1_0, point to New, and then click Multi-String Value.
  3. In the Name column, type BackConnectionHostNames, and then press ENTER.
  4. Right-click BackConnectionHostNames, and then click Modify. In the Value data box, type the CNAME or the DNS alias, that is used for the local shares on the computer, and then click OK.
    • Type each host name on a separate line.

See Calling WCF service hosted in IIS on the same machine as client throws authentication error for details.

0
votes

The solution for me was to set the AppPool from using the AppPoolIdentity to the NetworkService identity.

0
votes

I had the same problem, to solve it set specific user from domain in iis -> action sidebar->Basic Settings -> Connect as... -> specific user

enter image description here