1
votes

Using console app in C# to call lists.asmx getting 'http request is unauthorized with clien tauthentication scheme 'ntlm'. The authentication header received from the server was 'Negotiate, NTLM'.

Environment:

  • Kerberos turned on in QA & Production, not in Dev (stupid I know, but I don't admin any of the boxes)
  • Hitting a sharepoint webservice to GET data from a sharepoint list (lists.asmx).
  • Server uses ssl.

I get an error message in my qa environment as follows (can't paste the stacktrace as it's in a picture only):

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

Direct navigation to the list works fine from every machine.

  • Code works in a development environment (on the server) which does not have kerberos enabled (should be, but isn't. I CANNOT change this).
  • Code works against production from a desktop machine which does have kerberos enabled
  • Code does not work in a QA environment which does have kerberos enabled. This is where I get the error

To call the webservice I do this (no other security-related code involved)

XmlElement element = this.LIstsServiceClient.GetListItems(listName, '', query, fields, '300', null, null);

My app.config is as follows

    <configuration>
    <system.serviceModel>
      <behaviors>
        <endpointBehaviors>
          <behavior name="clientEndpointBehavior">
            <clientCredentials>
              <windows allowedImpersonationLevel="Delegation"/>
            </clientCredentials>
          </behavior>
        </endpointBehaviors>
      </behaviors>
      <bindings>
            <basicHttpBinding>
                <binding name="ListsSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="999999999" maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="999999" maxNameTableCharCount="16384" />
                    <security mode="Transport">
                      <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" realm="" />
                      <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
</basicHttpBinding>
<client>
         <endpoint address="https://servername/sitecollectionname/_vti_bin/Lists.asmx"
              binding="basicHttpBinding" bindingConfiguration="ListsSoap"
              contract="ListsService.ListsSoap" name="ListsSoap" behaviorConfiguration="clientEndpointBehavior"  >
            <identity>
              <servicePrincipalName value="spn" />
            </identity>
          </endpoint>
</client>
    </system.serviceModel>
</configuration>
5

5 Answers

2
votes

Have a look here

Enabled Anonymous access (username and password of domain user) Enabled Integrated Windows authentication

Or, as lextm-MSFT says, check you are passing a valid set of user credentials

1
votes

I resolved problem :

putting this is Config

<system.serviceModel>
    <bindings />
    <client />
</system.serviceModel>
0
votes

It is simply an authentication failure. Check if your console application sends a valid user credential to IIS that hosts this web service.

0
votes

I never did manage to find the answer to this, but mostly because I did not have access to consistently configured environments, hence I was unable to debug my code. I believe the issue to be a configuration problem, probably Kerberos related.

0
votes

I solved this by allowing impersonation on the client endpoint, which the Lists service seems to require for the first request it receives (possibly depending on which web method you're calling). The Lists service will, confusingly, perform authentication and validation internally and if it fails, generate 401, or 500 responses which make it seem like your request is failing in IIS before hitting the service when in fact, the service method is executing and returning errors.

<behaviors>
   <endpointBehaviors>
      <behavior name="SPServiceBehavior">
          <clientCredentials>
                <windows allowedImpersonationLevel="Impersonation" allowNtlm="True"/>
          </clientCredentials>
      </behavior>
   </endpointBehaviors>
</behaviors>

See my question here for all the details.