.Net Core 2.1 getting client machines windows user name

3.4k Views Asked by At

I am attempting to get the currently logged in user in Windows on the clients computer. I have tried using User.Identity.Name & WindowsIdentity.GetCurrent().Name. When I run the application locally through Visual Studio, it runs great. Meanwhile when I publish this same code to our IIS server when I run the this code, it returns "NT AUTHORITY\NETWORK SERVICE".

I thought this was going to be an easier task and started going through a bunch of different google searches with no luck (maybe its just that im new to .net core and am making a dumb mistake somewhere). Anyhow my server has Windows Authorization enabled (see image below).

Windows Authentication IIS

The project is a .net core 2.1 web application and I am working in C#. Any help with this would be great!

Note

My previous thread (now deleted) for this question was marked as a duplicate question (How get current user in asp.net core) I do not understand how this is a duplicate when in this question they are saying that their HttpContext is null. I do not have this issue, I return a user but it is NOT the client machine's user. Due to this I had to recreate this question. If there is a duplicate answer please post it in the comments let me review if it actually is the same and if it is, then we can mark it as a duplicate. Thank you.

I also tried using:

HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value

This was suggested in the duplicate answer post but this just gives me a null reference error.

Update #1

Just thought I would also include that my server has the following roles already installed:

Windows Auth role installed

Update #2

Here is the method getting the user name, it is the index.cshtml razor page that is initially loaded.

public async Task<IActionResult> OnGetAsync()
    {
        ILogger log = ApplicationLogger.CreateLogger("LoginFilter");
        log.LogError("Start");
        log.LogError("contextIdent: " + User.Identity.Name);
        log.LogError("windowsIdent: " + WindowsIdentity.GetCurrent().Name);
        log.LogError("environment: " + Environment.UserName);
        log.LogError("End");

        return Page();
    }

This outputs the following to the stdout log:

Hosting environment: Production
Content root path: C:\inetpub\wwwroot\MyApp
Now listening on: http://127.0.0.1:20316
Application started. Press Ctrl+C to shut down.
fail: LoginFilter[0]
      Start
fail: LoginFilter[0]
      contextIdent: NT AUTHORITY\NETWORK SERVICE
fail: LoginFilter[0]
      windowsIdent: NT AUTHORITY\NETWORK SERVICE
fail: LoginFilter[0]
      environment: MYENV$
fail: LoginFilter[0]
      End

Update #3

Added:

log.LogError("findFirst: " + User.FindFirst(ClaimTypes.NameIdentifier).Value);

After adding this the log generated the following:

Hosting environment: Production
Content root path: C:\inetpub\wwwroot\MyApp
Now listening on: http://127.0.0.1:35812
Application started. Press Ctrl+C to shut down.
fail: LoginFilter[0]
      Start
fail: LoginFilter[0]
      contextIdent: NT AUTHORITY\NETWORK SERVICE
fail: LoginFilter[0]
      windowsIdent: NT AUTHORITY\NETWORK SERVICE
fail: LoginFilter[0]
      environment: MYENV$
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.NullReferenceException: Object reference not set to an instance of an object.
   at MyApp.Pages.IndexModel.OnGetAsync()
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.ExecutorFactory.GenericTaskHandlerMethod.Convert[T](Object taskAsObject)
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.ExecutorFactory.GenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeHandlerMethodAsync()
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeNextPageFilterAsync()
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)

Update #4

I added to my Startup.cs ConfigureServices the following:

services.AddAuthentication(IISDefaults.AuthenticationScheme);

And into my index.cshtml:

var user = WindowsIdentity.GetCurrent();
WindowsIdentity.RunImpersonated(user.AccessToken, () =>
{
    var impersonatedUser = WindowsIdentity.GetCurrent();
    log.LogError("impersonated: " + impersonatedUser.Name);
});

As I had expected (due to the user being passed to impersonate still being "NT AUTHORITY\NETWORK SERVICE") the results are as follows:

Hosting environment: Production
Content root path: C:\inetpub\wwwroot\MyApp
Now listening on: http://127.0.0.1:36547
Application started. Press Ctrl+C to shut down.
fail: LoginFilter[0]
      Start
fail: LoginFilter[0]
      impersonated: NT AUTHORITY\NETWORK SERVICE
fail: LoginFilter[0]
      contextIdent: NT AUTHORITY\NETWORK SERVICE
fail: LoginFilter[0]
      windowsIdent: NT AUTHORITY\NETWORK SERVICE
fail: LoginFilter[0]
      environment: MYENV$
fail: LoginFilter[0]
      hcIdent: NT AUTHORITY\NETWORK SERVICE
fail: LoginFilter[0]
      End
Application is shutting down...
2

There are 2 best solutions below

0
On BEST ANSWER

Searching for a solution I ran into this site:

Identities for different IIS7 Authentication Configurations

Looking at the different identity names that are used with the different application pool settings I decided to try changing it. What kinda clued me into this is the user name I was getting back in my code (NT AUTHORITY\NETWORK SERVICE) was very similar to the Identity setting NetworkService. So I attempted trying to load the page after changing the application pools identity to LocalSystem and this solved my issue!

Below is a screenshot of the application pool setting that i changed:

Application Pool Identity Setting

Anyhow this solved my problem hope this helps someone who may have the same issue!

3
On

I just created a new ASP.NET Core 2.1 MVC Web Application Project from Template in Visual Studio. Checked "Windows Authentication" in the Template Wizard and

added User.Identity.Name

 public IActionResult Contact()
        {
            ViewData["Message"] = "User: " + User.Identity.Name; 

            return View();
        }

works out of the box on dev machine. You ran into problems only when moving to an production IIS? So it will be difficult to narrow down the diffs from remote.