Constrained Delegation works if App Pool is Local System but not if Network Service in IIS 7

delegationwindows-server-2008

I have an issue with Constrained Delegation and IIS 7 on Windows Server 2008.

We have a web application which uses impersonation to access a SQL Report Server. This has worked fine with IIS 6 with both Trusted for Delegation and Constrained Delegation. However we have run into an issue with IIS 7.

What I have been able to get it down to is this, On IIS 7, with the Application Pool running as NetworkService, and Constrained delegation configured, we get an HTTP 401 Unauthorised error from Report Server, with the Application Pool running as Local System the Impersonation works fine.

I have tested in both Classic and Integrated Pipeline.
Code from a very simple test page that simulates this issue is below. Running the same test page from an IIS 6 server of Windows 2003 works fine.
Any ideas of security policy, IIS configuration or even server features and roles that might effect this?

Please note I have checked Kerberos is working fine, and the constrained delegation configuration is correct.

private void testImpersonation()
{
  string url = "http://testsvr7/reportserver/";

  System.Security.Principal.WindowsIdentity user =
    (System.Security.Principal.WindowsIdentity)Context.User.Identity;
  System.Security.Principal.WindowsImpersonationContext WICTX = null;

  StringBuilder results = new StringBuilder();

  try
  {
     if (user != null)
     {
        WICTX = user.Impersonate();
        results.AppendFormat("<br />Impersonating, user: {0}",   
             System.Security.Principal.WindowsIdentity.GetCurrent().Name);

        System.Net.HttpWebRequest myHttpWebRequest =
             (HttpWebRequest)WebRequest.Create(url);

        // Assign the credentials of the user being impersonated.
        myHttpWebRequest.Credentials = CredentialCache.DefaultCredentials;

        System.Net.HttpWebResponse myHttpWebResponse =
             (HttpWebResponse)myHttpWebRequest.GetResponse();

        results.AppendFormat("<br />Authentication successful - {0}, {1}",
             url, CredentialCache.DefaultCredentials);
     }
  }
  catch (Exception ex)
  {
     results.AppendFormat("<br />Exception: {0}", ex.Message);
  }
  finally
  {
     if (WICTX != null)
     WICTX.Undo();
  }
  Response.Write(results.ToString());

Best Answer

I believe I have found the resolution - if I set the useAppPoolCredentials property of system.webServer/security/authentication/windowsAuthentication to "true" then the AppPool with NetworkService works fine with the Constrained Delegation.

Tested on both Windows Server 2008 and 2008 R2.

I am unsure why this is, and I did find it very hard to get really clear documentation on what this setting does and how it may effect this situation. You can set this value through the Configuration Editor in IIS Manager for IIS on 2008 R2.
Or use the following command (only way I found to do it for 2008 (not R2)):

%windir%\system32\inetsrv\appcmd set config "Default Web Site/MyApplication" /section:system.webServer/security/authentication/windowsAuthentication /useAppPoolCredentials:true /commit:MACHINE/WEBROOT/APPHOST