3

Can anyone please explain the function of the lines below:

WindowsIdentity wId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext wIdCon = wId.Impersonate();

That is used on a POST method with IIS basic authentication and works fine. If however the IIS authentication is set to windows the above no longer works.

There is simply way too much code to dump for an example.

sd_dracula
  • 3,796
  • 28
  • 87
  • 158

1 Answers1

4

The call to Impersonate() makes IIS pretend to be the requesting user from that point on. This is useful for a number of reasons, chiefly that the subsequent code will only work if the requesting user is not denied access.

This works for basic because the website is given the username and password and can therefore login as the user. Windows authentication is failing becuase it uses kerberos and is only given a ticket refering the the user - not the users password.

To get Windows authentication to work, you need to allow the website account (the one that is the app pool identity for your application) to impersonation users. This is done in the delegation tab of their account in Active Directory.

If they don't have a delegation tab, you first need to add an SPN (a Service Principal Name). The SPN allow clients to know which account is running the website and therefore how to encrypt to kerberos ticket such that the website can open it. It's all a way of allowing client and server to talk without every telling each other their passwords as long as they both trust a 3rd party (the AD server in the standard MS implementation).

This is all part of a common problem known as kerberos double hop. it all stems from the fact that Kerberos from the client to the website works (the website knows enough about the client users credentials to serve pages etc) but the 2nd hop from the website to the resource that requires the web users credentials is not being given them as the website account is not allowed to. For more info see understanding-kerberos-double-hop on msdn

EDIT:

Try running setspn /q http/machine_name_or_fqdn e.g.

setspn /q http/mywebbox
setspn /q http/mywebbox.my.domain.com

Which user are these spn's set against? IIS needs to have the appPool for the website running as same user as the SPN.

Once you've confirmed that, I'd suggest using the fiddler tool to check what is passing between the client and the server - confirm that is getting a 401 error response (i.e. you need to authenticate) and immediately retrying with the request having a valid kerberos header.

Once you've got the client to server talking via kerberos, you need to ensure the appPool account has been set in AD as allowed to delegate on behalf of users.

Grhm
  • 6,726
  • 4
  • 40
  • 64
  • Thank you very much for the detailed explanation, that makes a lot more sense now :) – sd_dracula Aug 15 '12 at 07:19
  • How to allow impersonation in IIS? Just enable it from the Authentication -> ASP.NET Impersonation and set to Specific User? The specifis user being a local machine admin account? – sd_dracula Aug 15 '12 at 07:25
  • I've only ever done it will IIS running as a domain account (usually one created to be the service account for that website) or with IIS running as the local "Network Service" account - in which case you need to SPN for the computer account in AD. – Grhm Aug 15 '12 at 10:59
  • I don't think there is a way to get a local user to work with kerberos in AD. The concept is that both client and server exchange enougth details to accept the other party is who they say they are without divulging enough details that someone else use them to claim to someone they're not. It only works if both parties use a 3rd party trusted by both to authenticate them - and that is the AD server. A local user account does not have any relationship with the AD server (but the machine account does as the machine belongs to the domain and has an AD account). – Grhm Aug 15 '12 at 11:07
  • Makes sense. The only thing is that the AD server is locked down have no way of checking the SPN. There is a network service account and I will try that one, perhaps it will do. – sd_dracula Aug 15 '12 at 13:09
  • Should ASP.NET Impersonation be enabled or disabled in IIS? And the NetworkService should be set in the Identity of the Process Model inside the AppPool settings? – sd_dracula Aug 15 '12 at 13:49
  • You can check the SPNs via the SetSPN utility. e.g. on my win7 machine `setspn /q http/*` will query any http SPNs within my domain. You don't need rights to alter AD to query it, so I believe it should work with a standard user account and without any special AD access right being granted. – Grhm Aug 15 '12 at 15:02
  • `setspn /q http/*` give: Existing SPN found! on my Win 7 machine. My account has full admin rights and I have tried setting it to that in IIs but still no go. – sd_dracula Aug 16 '12 at 11:54