.Net Core 2.1获取客户端计算机的Windows用户名

时间:2018-11-20 13:56:58

标签: c# .net .net-core .net-core-2.1

我正在尝试在客户端计算机上的Windows中获取当前登录的用户。我尝试使用User.Identity.Name和WindowsIdentity.GetCurrent()。Name。当我通过Visual Studio在本地运行该应用程序时,它运行得很好。同时,当我在运行此代码时将相同的代码发布到IIS服务器时,它将返回“ NT AUTHORITY \ NETWORK SERVICE”。

我认为这将是一件容易的事,并开始经历很多不同的Google搜索,但都没有碰到运气(也许这只是.net核心的新功能,并且在某个地方犯了一个愚蠢的错误)。无论如何,我的服务器已启用Windows授权(请参见下图)。

Windows Authentication IIS

该项目是一个.net core 2.1 Web应用程序,我正在C#中工作。任何帮助都会很棒!

注意

我先前针对此问题的线程(现已删除)被标记为重复问题(How get current user in asp.net core),当他们在此问题中说自己的HttpContext为null时,我不明白这是重复的。我没有这个问题,我返回了一个用户,但它不是客户端计算机的用户。因此,我不得不重新创建这个问题。如果有重复的答案,请将其张贴在评论中,让我查看它是否确实相同,如果是,那么我们可以将其标记为重复。谢谢。

我也尝试使用:

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

在重复的答案文章中建议这样做,但这只是给我一个空引用错误。

更新#1

只是想我也要指出我的服务器已经安装了以下角色:

Windows Auth role installed

更新#2

这是获取用户名的方法,它是最初加载的index.cshtml剃刀页面。

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();
    }

这会将以下内容输出到标准输出日志:

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

更新#3

添加:

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

添加此日志后,日志将生成以下内容:

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)

更新#4

我在Startup.cs ConfigureServices中添加了以下内容:

services.AddAuthentication(IISDefaults.AuthenticationScheme);

并进入我的index.cshtml:

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

正如我所期望的(由于用户被传递为仍然扮演“ NT AUTHORITY \ NETWORK SERVICE”的角色),结果如下:

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 个答案:

答案 0 :(得分:1)

寻找解决方案时遇到了这个网站:

Identities for different IIS7 Authentication Configurations

查看与不同应用程序池设置一起使用的不同标识名,我决定尝试对其进行更改。导致我误解的是我在代码中重新获得的用户名( NT AUTHORITY \ NETWORK SERVICE )与身份设置 NetworkService 非常相似。因此,我尝试在将应用程序池标识更改为 LocalSystem 后尝试加载页面,这解决了我的问题!

以下是我更改的应用程序池设置的屏幕截图:

Application Pool Identity Setting

无论如何,这解决了我的问题,希望这对可能遇到相同问题的人有所帮助!

答案 1 :(得分:0)

我刚刚从Visual Studio中的模板创建了一个新的ASP.NET Core 2.1 MVC Web应用程序项目。在模板向导中选中“ Windows身份验证”,然后

添加了User.Identity.Name

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

            return View();
        }

在开发机器上开箱即用。 您仅在移至生产IIS时才遇到问题吗? 因此,很难缩小远程的差异。