C# – Setting up NTLM Authentication with WCF to Sharepoint Web Services

chttpsntlmsharepointwcf

I have been having a lot of difficulty setting up my WCF service to talk to Sharepoint Web services, specifically I am trying to use the Lists.asmx and Copy.asmx services.

I got it working using an http link to sharepoint for development, but now we need to switch to an HTTPS link. I got the web reference setup and updated for this link, but when it tries to call a service (ex: GetListItems) it errors out with the following error:
The request failed with HTTP status 401: Unauthorized.

I then tried to see what type of authentication our Sharepoint Server uses, which turns out to be NTLM. I then tried to configure out web.config file for this. Here is the entire web.config file:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
            <section name="InventoryService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
        </sectionGroup>
    </configSections>
    <appSettings/>
    <connectionStrings/>
    <system.web>
        <compilation debug="true" targetFramework="4.0">
        </compilation>
        <!--
        The <authentication> section enables configuration 
        of the security authentication mode used by 
        ASP.NET to identify an incoming user. 
    -->
        <authentication mode="Windows"/>
        <!--
        The <customErrors> section enables configuration 
        of what to do if/when an unhandled error occurs 
        during the execution of a request. Specifically, 
        it enables developers to configure html error pages 
        to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
         <error statusCode="403" redirect="NoAccess.htm" />
         <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
    -->
        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/></system.web>
    <!-- 
      The system.webServer section is required for running ASP.NET AJAX under Internet
      Information Services 7.0.  It is not necessary for previous version of IIS.
  -->
    <system.serviceModel>
        <bindings>
   <basicHttpBinding>
    <binding name="NewBinding0">
     <security mode="TransportCredentialOnly">
      <transport clientCredentialType="Ntlm" proxyCredentialType="None" />
     </security>
    </binding>
   </basicHttpBinding>
  </bindings>
  <services>
   <service behaviorConfiguration="InventoryService.Service1Behavior"
    name="InventoryService.InventoryService">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="NewBinding0"
     contract="InventoryService.IInventoryService">
     <identity>
      <dns value="localhost" />
     </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
   </service>
  </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="InventoryService.Service1Behavior">
                    <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                    <serviceMetadata httpGetEnabled="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="true"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
    <applicationSettings>
        <InventoryService.Properties.Settings>
   <setting name="InventoryService_WSCopy_Copy" serializeAs="String">
    <value>http://site/_vti_bin/Copy.asmx</value>
   </setting>
   <setting name="InventoryService_SharepointLists_Lists" serializeAs="String">
    <value>https://site/_vti_bin/Lists.asmx</value>
   </setting>
  </InventoryService.Properties.Settings>
    </applicationSettings>
</configuration>

If anyone has a clue if I setup this config file correctly for NTLM, that would be really helpful.

If this is setup correctly, then I guess I will move on to the next question about if I setup the credentials correctly:

inventoryList = new SharepointLists.Lists();
inventoryList.Url = "https://fullsiteurl/_vti_bin/Lists.asmx";
inventoryList.Credentials = new System.Net.NetworkCredential("user", "pass", "domain");

If someone could go over this, that would also be very helpful.

Again I know that the config file is pretty long and I highly appreciate it if you go through it let me know if I setup NTLM authentication correctly.

If all this checks out ok, then I have no idea where to start on getting the HTTPS link with sharepoint working (The existing HTTP link to sharepoint is still accessible for the time being, until I can get the service working with the HTTPS link).

Best Answer

Make sure the specified user has access to the ASMX with the browser.

Make sure the user has (at minimum) Read permission to the target library.

Also, make sure the user has the Use Remote Interfaces premission (WSS 3.0: Site settings, Advanced permissions, Settings - Permission Levels, choose corresponding permission level).

Also, if you are using MOSS 2007, SOAP access can be disabled in the central admin.

I don't have Sharepoint 2010 available at the moment so I cannot check, but I expect the settings to be corresponding.

Edit:

If everything works great under normal HTTP, I would look at the way that HTTPS was enabled.

Take a look at this site "How to enable SSL on a SharePoint 2010 web application", especially the second part (about 1/3rd of the page, regarding adding an alternate access mapping).

Hope this helps.

Related Topic