我正在尝试在客户端计算机上的Windows中获取当前登录的用户。我尝试使用User.Identity.Name和WindowsIdentity.GetCurrent()。Name。当我通过Visual Studio在本地运行该应用程序时,它运行得很好。同时,当我在运行此代码时将相同的代码发布到IIS服务器时,它将返回“ NT AUTHORITY \ NETWORK SERVICE”。
我认为这将是一件容易的事,并开始经历很多不同的Google搜索,但都没有碰到运气(也许这只是.net核心的新功能,并且在某个地方犯了一个愚蠢的错误)。无论如何,我的服务器已启用Windows授权(请参见下图)。
该项目是一个.net core 2.1 Web应用程序,我正在C#中工作。任何帮助都会很棒!
注意
我先前针对此问题的线程(现已删除)被标记为重复问题(How get current user in asp.net core),当他们在此问题中说自己的HttpContext为null时,我不明白这是重复的。我没有这个问题,我返回了一个用户,但它不是客户端计算机的用户。因此,我不得不重新创建这个问题。如果有重复的答案,请将其张贴在评论中,让我查看它是否确实相同,如果是,那么我们可以将其标记为重复。谢谢。
我也尝试使用:
HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value
在重复的答案文章中建议这样做,但这只是给我一个空引用错误。
更新#1
只是想我也要指出我的服务器已经安装了以下角色:
更新#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...
答案 0 :(得分:1)
寻找解决方案时遇到了这个网站:
Identities for different IIS7 Authentication Configurations
查看与不同应用程序池设置一起使用的不同标识名,我决定尝试对其进行更改。导致我误解的是我在代码中重新获得的用户名( NT AUTHORITY \ NETWORK SERVICE )与身份设置 NetworkService 非常相似。因此,我尝试在将应用程序池标识更改为 LocalSystem 后尝试加载页面,这解决了我的问题!
以下是我更改的应用程序池设置的屏幕截图:
无论如何,这解决了我的问题,希望这对可能遇到相同问题的人有所帮助!
答案 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时才遇到问题吗? 因此,很难缩小远程的差异。