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

TylerH
  • 20,799
  • 66
  • 75
  • 101
Chiramisu
  • 4,687
  • 7
  • 47
  • 77

2 Answers2

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.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Chiramisu
  • 4,687
  • 7
  • 47
  • 77
  • 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 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? – tone May 01 '17 at 00:09
  • @tone 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. – Junior Nov 04 '17 at 22:41
  • @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? – Junior Nov 04 '17 at 22:50
  • @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. – Chiramisu Nov 08 '17 at 18:15
  • @Chiramisu Please don't revert edits that improve the formatting of a post, including removing noise and fixing things like incorrectly spelled words. – TylerH Aug 21 '19 at 14:13
  • @TylerH I rolled them back because your edits did not add any value under the guideline [When should I edit posts?](https://stackoverflow.com/help/editing). – Chiramisu Sep 01 '19 at 16:09
  • @Chiramisu Fixing misspelled words and removing fluff are clear value-adds. – TylerH Sep 02 '19 at 15:16
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.

Community
  • 1
  • 1
Donal Lafferty
  • 5,807
  • 7
  • 43
  • 60
  • Where does the `User` class (as in `User.Identity`) come from? – Coxy Apr 05 '16 at 07:44
  • 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. – Corrodias Apr 25 '17 at 20:46