Impersonate Domain User with Integrated Pipeline
S

2

23

In an local Intranet environment, are we doomed to use "Classic" pipeline mode in our App Pool if we want to use Impersonate our Windows domain users, or is there a new way to declaratively "run as" them (so-to-speak)?

My goal is to use Windows Authentication for local web applications on my Intranet so users can authenticate and run apps under their active directory account (principle). Every time I try this (Using the NetworkService identity of course), I get this error:

screenshot of error message

Spokane answered 19/10, 2012 at 1:52 Comment(0)
S
27

I wrote a small app to display the current user's network username grabbed from several different places such as Page.User.Identity.Name. I also grabbed information about the domain user using a couple different methods for querying Active Directory. All this to validate the following.

I have found two primary modes for running your application using Windows Authentication, which is primarily used in an Intranet environment according to my research. Here are the minimum essential elements of the configurations:

Classic Mode

  • AppPool - Managed Pipeline set to Classic mode.
  • AppPool - Identity set to Network Service.
  • Authentication - Disabled: Anonymous Authentication
  • Authentication - Enabled: ASP.NET Impersonation
  • Authentication - Enabled: Windows Authentication
  • Providers - Disabled: Kerberos
  • Advanced Settings - Kernel Mode: Either

Integrated Mode

  • AppPool - Managed Pipeline set to Integrated mode.
  • AppPool - Identity set to Network Service.
  • Authentication - Disabled: Anonymous Authentication
  • Authentication - Disabled: ASP.NET Impersonation
  • Authentication - Enabled: Windows Authentication
  • Providers - Enabled: Kerberos
  • Advanced Settings - Kernel Mode: Disabled

Now here's the kicker!!

If you want to use Integrated mode (which is ideal as it yields much more functionality, and well, integration) you will need to have enabled Delegation. Here are a couple must-read articles to understand the basics of Delegation, and by extension Dynamic SPN Registration. Since this gets into more Kerberos and security considerations that you probably care to delve into, it might be easier to just stick with Classic mode where all you have to do is enable Impersonation and call it a day; or else cheat and disable validateIntegratedModeConfiguration.

Spokane answered 29/10, 2012 at 17:23 Comment(7)
I just created a new MVC app in Visual Studio 2017 and set the authentication to Windows Authentication in the set up wizard (also selected .net framework 4.6.1) and then ran the app, and it automatically recognised the windows user. Looking in the web.config file, it doesn't have the identity/impersonate line at all. All it has is <authentication mode="Windows" /> <authorization> <deny users="?" /> </authorization> so I'm wondering why you have to go to all this effort, or is that something that's already been configured in my environment, and nothing to do with .net?Fascicule
@Fascicule When you run the app on production server is different that using IIS express on your local machine. Your local machine will not have a problem delegating your credentials. At least what I have seen.Pasqualepasqueflower
@Chiramisu, using the Classic setup you mention above allowed me to obtain the correct username, but I am not able to delegate the username/password to another service/SDK. Regarding the Integrated Mode, does every user that use my app need to have Kerberos enable or is it only the user that is running the PoolApp? When I change everything to match the Integrated setup, I can't log into the app any more. It just keep prompting me to provide my username/password. Any idea?Pasqualepasqueflower
@MikeA Make sure that within your Windows Authentication > Providers, you have Kerberos listed first. Beyond that, I'm sorry but I'm not sure I can be of much help.Spokane
@Spokane Please don't revert edits that improve the formatting of a post, including removing noise and fixing things like incorrectly spelled words.Surrealism
@Surrealism I rolled them back because your edits did not add any value under the guideline When should I edit posts?.Spokane
@Spokane Fixing misspelled words and removing fluff are clear value-adds.Surrealism
J
13

No, but "Integrated" pipeline requires you manually impersonate the Windows Authenticated user. At least in IIS8.5, that is.

Why? Classic impersonation break .NET's async features. Specifically, it is hard to manage the WindowsIdentity of a thread when it is being used by multiple users at the same time.

How? Use a WindowsImpersonationContext e.g.

// Start with identity assigned by IIS Application Pool
var current = System.Security.Principal.WindowsIdentity.GetCurrent();

// Enable Windows Authentication in ASP.NET *and* IIS, which ensures 
// User.Identity is a WindowsIdentity
WindowsIdentity clientId = (WindowsIdentity)User.Identity;

// When 'using' block ends, the thread reverts back to previous Windows identity,
// because under the hood WindowsImpersonationContext.Undo() is called by Dispose()
using (WindowsImpersonationContext wic = clientId.Impersonate())
{
    // WindowsIdentity will have changed to match clientId
    current = System.Security.Principal.WindowsIdentity.GetCurrent();
}
// Back to the original identity
current = System.Security.Principal.WindowsIdentity.GetCurrent();

Problems? Sometimes you need to use delegation instead of impersonation.

Jolin answered 27/3, 2014 at 15:43 Comment(2)
Where does the User class (as in User.Identity) come from?Coolth
It is a property in the MVC Controller class, so you'd access it within an action in a controller and pass it where you need to.Vi

© 2022 - 2024 — McMap. All rights reserved.