Impersonation Shenanigans?

Ever have different behavior when connecting to an application sever remotely vs. locally? Here’s a common gotcha than can be tough to unwind. This is described here in an AzMan scenario but any app server that makes any network calls can have similar problems with the same root cause.

Sometimes developers see that they have different access results depending on whether they hit an app server locally vs. remotely. For example, when you use the same box that the app server is running on to browse to a web page of the app server everything works; but when you use a browser on a different machine to browse to the app server you don’t have access to some resource (or get other weird problems.) This is a common road bump when developing a service that is impersonating the client and then doing a query to another machine (such as a DC) as the client.

This difference is because when a local logon (a logon that was done on the same machine as that which the app server is running on) authenticates to the application server the local logon token is usually reused for the logon token to the application server. If this token is then impersonated when a query to a remote machine is done then the call will authenticate to the remote machine as the client. The local logon allows the client to be authenticated to the remote machine because a local (interactive) logon has a password (or some credential) associated with it and therefore is capable of authenticating to another machine. For a remote client (using integrated auth) a "network" token is usually created on the web service machine; it will not have a credential associated with it so it cannot make a second hop as a client who authenticated to the application server (that would require delegation which takes more setup.) In this case the remote call will authenticate to the remote machine as the app server account.

One way to catch this is if you can monitor the connections on the machine you’re making the impersonated query to (this remote query may be done in an API that reads from another machine such as a DC) and you can check who is connecting. If you’re connecting as the machine account of the app server then the impersonation did not carry through the impersonated call to the remote machine.

If you think you’re running into this situation and for some reason you want to maintain the impersonation to the back-end machine lookup Kerberos delegation on MSDN / TechNet, but In AzMan scenarios it’s probably not the way to fix this. AzMan apps typically use a trusted-subsystem model in which you don’t impersonate the client and access resources but instead access resources as the app server account. See the AzMan Dev Whitepaper for more on trusted-subsystem.

In AzMan people hit this problem when accessing the DC via the InitializeClientContextFromName call or at some point during authorization validation (AccessCheck etc.) To avoid this in AzMan make sure your not impersonating (unless you really want to for some reason) and then make sure the app service account has access to the back-end resource s the app needs to access. For AzMan apps that’s typically the authorization store. And if you’re using InitializeClientContextFromName the app server account need access to read user objects in AD.

To access the AzMan policy store you need to give the app server account at least read access to the store (see the AzMan Dev Whitepaper for info on that.)

To give the application server account access to the user objects (if you’re using InitializeClientContextFromName) put the web service account in the Windows Authorization Access Group on the DC (or the Pre-Win2k compatibility Access Group; that grants broader than necessary read permissions in the domain but it avoids some down-level cases that membership in the WAA group does not.) See https://support.microsoft.com/kb/331951 for in-depth info on granting access to the user tokenGroupsGlobalAndUniversal attribute.)

And as always, if you’re using InitializeClientContextFromName use InitializeClientContextfromToken if at all possible.

 

-Dave McPherson