locked
Unable to get Windows Authentication/Impersonation working [MVC 5, IIS 8, Server 2012 R2] RRS feed

  • Question

  • User-2076825254 posted

    Hello Everyone

    First, some context about this: We are developing a web application for internal use within our domain/corporate network. Technologies used are an MVC 5 application running on an IIS 8 instance on a Server 2012 R2 server. I have created a minimal sample within our application to try to figure out the problem, why authentication and impersonation is not working as expected.

    Problem is this: According to this article https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff649264(v=pandp.10) there should be a way to get the user that is authenticated from within the ASP.NET using any of these three identities available. On the test server (Windows 7 with IIS 7.5), these properties are all pointing to DOMAIN\USER, but on the production instance the output is as follows (the identity of the AppPool).

    HttpContext.User.Identity NT AUTHORITY\NETWORK SERVICE
    System.Security.Principal.WindowsIdentity.GetCurrent() NT AUTHORITY\NETWORK SERVICE
    Thread.CurrentPrincipal.Identity NT AUTHORITY\NETWORK SERVICE

    In web.config the settings are all made as follows (like in https://stackoverflow.com/questions/30226024/getting-the-name-of-the-current-windows-user-returning-iis-apppool-sitename):

    1. Enable Windows Authentication
    2. Disable Anonymous Authentication
    3. Set Impersonation to True
    <identity impersonate="true" />
    <authentication mode="Windows" />

    Debug output shows that authentication mode is actually using Windows Authentication and testing with non-domain-joined clients, this is actually the case. Entering any credentials that are not domain logins or local server windows user accounts, a 401 unauthorized is returned successfully. This means that authentication works.

    Then why is none of the listed properties in ASP.NET set to the identity of the authenticated user making the HTTP request?

    Thanks for helping!

    Tuesday, November 20, 2018 4:11 PM

Answers

  • User-2076825254 posted

    I have found the solution to this problem: There was some unknown config in the IIS Site configuration that made it not give the correct data to ASP.NET. Deleting and re-creating the site in the IIS control panel solved this issue. What the root-cause was, I can't say though.

    That this would solve the problem got apparent when I had ported the whole site to ASP.NET Core first (because it's better anyways) and created a new site for testing (worked fine), then copied the whole folder over to the old location and the ASP.NET Core site also stopped working correctly. So the reason was also never ASP.NET, it was always on the IIS side.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 5, 2018 8:36 PM

All replies

  • User753101303 posted

    Hi,

    You are 100% sure you are showing System.Web.httpContext.User.Identity.Name ? You tried to show IsAuthenticated and AuthenticationType ? Also disable impersonation.

    The above property should ALWAYS return the authenticated user for this web request (that is if authenticated or "blank").

    Forget about the thread or Windows identity which is to return the account under which the code runs (and so if using that mistakenly you have to enable impersonation even if you don't really need it to get the "expected" result).

    Tuesday, November 20, 2018 6:18 PM
  • User-474980206 posted

    if your clients are getting a 401, then I'd check that authentication mode is set correct. use IIS to check the configuration of the application.

    Tuesday, November 20, 2018 8:55 PM
  • User-2076825254 posted

    Hello Patrice

    I'm not entirely sure, but it's the HttpContext exposed by the Controller base class as shown below:
    HttpContext

    The content of these variables is as follows:

    Authentication Type Negotiate
    Authentication Mode Windows
    User Is Authenticated True
    HttpContext.User.Identity NT AUTHORITY\NETWORK SERVICE
    NT AUTHORITY\NETWORK SERVICE
    System.Security.Principal.WindowsIdentity.GetCurrent() NT AUTHORITY\NETWORK SERVICE
    Thread.CurrentPrincipal.Identity NT AUTHORITY\NETWORK SERVICE

    This is really mindboggling, because Authentication Mode is correct according to the API and the user gets successfully authenticated. Can you confirm if I'm using the correct property to access the System.Web.httpContext.User.Identity.Name property?

    @Bruce: I only get the 401 Unauthorized when purposefully giving false credentials, that's not the issue. It's the expected response.

    Thanks!

    Hans

    Wednesday, November 21, 2018 12:42 PM
  • User753101303 posted

    Yes this is System.Web.HttpContext.User.Identity.Name, User being exposed as well at places where you frequently need to use it. You are 100% sure you are showing the correct property in your HTML table ? BTW you disabled impersonation? This is not needed.

    You are using Remote desktop ? It seems someone else have the same problem when using a VPN, and running remote desktop to use a browser on the machine where IIS is running.

    The behavior I saw until now is that User.Identity.Name is ALWAYS the browser side authenticated user (it works even for other authentication methods such as Form, Azure AD, ADFS etc...). Other methods are returning the account under which the code runs and so it depends on the site configuration (and the IMHO wrong advice sometimes given is to enable impersonation).

    Thursday, November 22, 2018 6:11 PM
  • User-2076825254 posted

    Thanks for the reply!

    No change after disabling impersonation. Not using RDP or a VPN either, it's just standard client/server connection with the browser running on my personal device. I really don't know what might be wrong anymore.

    Monday, November 26, 2018 10:14 AM
  • User753101303 posted

    I don't remember to have seen someone reporting this kind of behavior. What if you check the IIS log ? Which value do you see in csUserName ?

    By default log files are stored at C:\inetpub\logs\LogFiles

    Monday, November 26, 2018 12:14 PM
  • User-2076825254 posted

    Looking at the logs, the correct DOMAIN\USER value is recorded there.

    Monday, November 26, 2018 12:32 PM
  • User753101303 posted

    Ah and so once again you are 100% sure you are showing System.Web.httpContext.User.Identity.Name or could it be a mistake in your code which would show the value returned by another method claiming it to be User.Identity.Name ? It should really return the value you are seeing in the IIS log.

    If it still doesn't work I would restart with a  brand new project with really the minimal amount of code (could it be some code that changes the expected user identity ?). If IIS is left alone, it should really show the same value than the one shown in the IIS log.

    Monday, November 26, 2018 1:10 PM
  • User-2076825254 posted

    Do you have a known-good sample to get the User.Identity.Name? A Razor minimal sample would probably be the minimum working sample.

    I have made a pastebin here with the current code example: https://pastebin.com/ikypFfrS

    What is even more odd, is that by deploying the same project to the Win7-based test server, there are no issues whatsoever there. Is there a comprehensive list of config file locations for IIS that I could diff to check what setting might be different.

    Monday, November 26, 2018 2:18 PM
  • User753101303 posted

    What if you add [Authorize] to your controller or you add a global filter ?

    I find really weird that the IIS log shows the correct value while User.Identity.Name is showing the application pooll account ??? I'm not sure I would know how to get this behavior if I wanted to get it.

    Monday, November 26, 2018 4:30 PM
  • User475983607 posted

    I'm guessing this is a double hop situation where the web server is making outbound requests to a service or DB.  At least that would explain the problem statement.

    Monday, November 26, 2018 4:40 PM
  • User-2076825254 posted

    Actually, this isn't the case: There is the client on the browser, the IIS hosting the ASP.NET MVC application and a single SQL server that is referenced only using a connection string with embedded SQL username and password (non-AD-based). The SQL server runs on the same WinServer 2012 instance.

    Thursday, November 29, 2018 9:03 AM
  • User-2076825254 posted

    I have found the solution to this problem: There was some unknown config in the IIS Site configuration that made it not give the correct data to ASP.NET. Deleting and re-creating the site in the IIS control panel solved this issue. What the root-cause was, I can't say though.

    That this would solve the problem got apparent when I had ported the whole site to ASP.NET Core first (because it's better anyways) and created a new site for testing (worked fine), then copied the whole folder over to the old location and the ASP.NET Core site also stopped working correctly. So the reason was also never ASP.NET, it was always on the IIS side.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 5, 2018 8:36 PM