0
votes

I have two custom web services built on top of SharePoint. We switched servers and upgraded the site from 2008 to 2010 over the weekend. I now get the following errors on each web service when viewed through the .NET web service wrapper.

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

and

System.Net.WebException: The request failed with HTTP status 401: Unauthorized.

The web services have dlls that live in the GAC and the ASMX files live in the LAYOUTS hive folder. These worked fine before the upgrade/server move.

What I think is happening is that the default windows credentials aren't being passed to the service. My web service calls SharePoint web services to get list content.

Here's an example of one of the calls that returns a 401:

<WebMethod()> _
Public Function TestGetUserInfo() As String
    Dim userService As New SharepointUser.UserGroup
    userService.Credentials = System.Net.CredentialCache.DefaultCredentials

    Dim UserInfoXML As XmlNode = userService.GetUserInfo(User.Identity.Name)

    Return UserInfoXML.ChildNodes(0).Attributes("Name").Value
End Function

This call goes against: http://{DomainName}/_vti_bin/Lists.asmx?wsdl

I've verified that user.identity.name returns the correct logged in user info. I think it's the system.net.credentialcahche.defaultcredentials that's not working. I've also tried .defaultnetworkcredentials with no luck.

This is what I have in the web.config:

  <system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<bindings>
  <basicHttpBinding>
    <binding name="projectBasicHttpConf" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="true" maxBufferSize="4194304" maxReceivedMessageSize="500000000" messageEncoding="Text" transferMode="StreamedResponse">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
    <binding name="BasicHttpBindingWithWindowsAuthentication">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" proxyCredentialType="None" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
    <binding name="SPFilesAccessServiceSoap" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<behaviors>
  <endpointBehaviors>
    <behavior name="clientEndPointBehavior">
      <clientCredentials>
        <windows allowedImpersonationLevel="Impersonation" />
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

Under system.web:

<authentication mode="Windows" />
<identity impersonate="true" />

I've gone back and forth with anonymous authentication with no luck.

In IIS I have windows authentication enabled and NTLM as my provider.

Any ideas on how to fix this? Thanks so much for reading.

-Nate

3

3 Answers

0
votes

I never figured it out. I did a workaround where I called the Microsoft.Sharepoint namespace stuff directly instead of calling a web service. That bypassed the security issues.

0
votes

all u need to pass from the client is System.Net.NetworkCredentials("Username",Password","Domain");

It should solve the problem I guess.

0
votes

Since you solved this with using the server object model instead of a web service call (which will only work on the server), this may be the loop back check feature causing the 401s. Here is the MS KB- http://support.microsoft.com/kb/896861

It is recommended to use the specify hosts method instead of the disable registry setting.