5
votes

Situation:

I have a .NET asmx web service deployed on my web server. This service calls a service on another server (our SharePoint server, if that's relevant). I want to impersonate/delegate the call to the SharePoint service from my web service by using the credentials of the client.

Problem:

I'm getting a 401 response back from the SharePoint service when I call MY Web Service and it calls SharePoint.

Setup:

  • My web server is running IIS 7. The app pool is running under "Network Service"
  • On my Windows Server 2003 domain controller the web server has "Trusted for Delegation (Kerberos Only)" enabled.
  • In ISS my app has Anonymous Authentication Disabled, Impersonation Enabled, and Windows Authentication Enabled with all three providers enabled (Negotiate:Kerberos, Negotiate, and NTLM)
  • The SharePoint server is set up with Anonymous Enabled, Impersonation enabled and Windows Authentication Enabled with ONLY provider NTLM enabled.

I can see on the SharePoint logs that when I run locally in Visual Studio a username is getting passed through (and the service works correctly) but when I run it on the web server NO username is on the log file and I get a 401 error

What an I setting up wrong to make the Kerberos delegation work?

Ideas? Thanks!

3

3 Answers

5
votes

Platform:

Using IIS7 this is what I did on BOTH servers. The first server and the second that we want the Kerberos authentication to "hop" to.

Step 1:

For the IIS site that has the services in it that you are calling (on each server) go into IIS manager, click on the site on the left under Connections and open up the "Authentication" section under IIS. Set "ASP.NET Impersonation" to Enabled and 'Windows Authentication" to Enabled. All other options under Authentication (Ananymous, Forms, etc.) should be be set to Disabled.

Under "Windows Authentication" right click and select "Providers". Set the only provider to be "Negotiate:Kerberos" (This forces Kerberos. If you want, after you get Kerberos working you can use both the "Negotiate" and "NTLM" providers and remove "Negotiate:Kerberos" so that clients unable to do Kerberos can connect. Note: I currently have mine set to "Negotiate" and "NTLM" and it seems to work)

Under "Windows Authentication" right click and select "Advanced Settings". Uncheck the "Enable Kernal-mode" box. (My Extended Protection option was set to off, didn't try anything else)

Step 2:

For each server you have to set up SPNs. The SPNs would be the following (either A OR B):

A:

If your app pool is running under an IDENTITIY that is a DOMAIN ACCOUNT add the following SPNs to THAT DOMAIN ACCOUNT on the domain controller

http/COMPUTER_NETBIOS_NAME 
http/COMPUTER_NETBIOS_NAME.FULLY_QUALIFIED_DOMAIN_NAME 
http://COMPUTER_NETBIOS_NAME.FULLY_QUALIFIED_DOMAIN_NAME

(if your not running on the default port, also add an additional 3 entries with the port name attached: http/COMPUTER_NETBIOS_NAME:PORT etc.)

B:

If your app pool is running under the IDENTITY "NetworkService" then add the same SPNs as above except replace "http" with "HOST" BUT ADD THEN TO COMPUTER_NETBIOS_NAME on your domain controller.

I'm still working to implement this in production, but this is what works for me in my Test environment. I'll keep this updated as I find out more.

Note:

This works if you are using the COMPUTER_NETBIOS_NAME directly in the url when you connect. If you are using a alias (www.mysite.mydomain.com) or the IP address directly this will not work. I believe, although I have not fully tested it, that you would have to folle the steps above but replace COMPUTER_NETBIOS_NAME with the alias or IP address when adding the SPNs. (or add it with both the netbios and the alias/ip, not really sure)

Also, if you get an error about a setting not being valid for integrated... after you turn on the "ASP.NET Impersonation" then you might need to add

<validation validateIntegratedModeConfiguration="false" />

to your web.config in the system.webServer section

1
votes

Try this:

Move Negotiate to the top of the Providers' list. And, in the applicationHost.config file usually under C:\Windows\System32\inetsrv\config, add useKernelMode="true" useAppPoolCredentials="true" to the <windowsAuthentication> tag under the <location> tag for your application, like below:

<location path="YOUR_APPLICATION_PATH">
    <system.webServer>
        <security>
            <authentication>
                <anonymousAuthentication enabled="false" />
                <windowsAuthentication enabled="true" useKernelMode="true" useAppPoolCredentials="true">
                    <providers>
                        <clear />
                        <add value="Negotiate" />
                        <add value="NTLM" />
                    </providers>
                </windowsAuthentication>
            </authentication>
        </security>
    </system.webServer>
</location>
1
votes

Delegation requires Kerberos. You'll have to make the SharePoint server support authentication with Kerberos.