简体   繁体   English

在ASP.NET MVC 6(vNext)中Thread.CurrentPrincipal Identity.Name为null

[英]Thread.CurrentPrincipal Identity.Name is null in asp.net mvc 6 (vNext)

I am developing a web application using Asp.Net MVC6 (vNext), Identity 3.0.* beta3. 我正在使用Asp.Net MVC6(vNext),Identity 3.0。* beta3开发Web应用程序。 This is 3-tier application with UI, Services and DB. 这是具有UI,服务和数据库的3层应用程序。 I am able to sign in user with SignInManager class of Asp.net identity, and I am trying to retrieve user details with roles & claims in the service layer so that I can verify if user has permission to take certain actions. 我能够使用Asp.net身份的SignInManager类登录用户,并且尝试在服务层中检索具有角色和声明的用户详细信息,以便可以验证用户是否有权执行某些操作。

How do we get Current username from current request principal identity in the service layer. 我们如何从服务层中的当前请求主体身份获取当前用户名。 In MVC 5, I have used Thread.CurrentPrincipal to do this. 在MVC 5中,我已经使用Thread.CurrentPrincipal来做到这一点。 But in MVC6 Identity.Name of Thread.CurrentPrincipal is set to null. 但是在MVC6中,将Thread.CurrentPrincipal Identity.Name设置为null。

Can someone let me know how I can do this? 有人可以让我知道我该怎么做吗? Also, if you have any better solution, please let me know. 另外,如果您有更好的解决方案,请告诉我。

If you've called AddIdentity() in your Startup.cs or wherever you configure your dependency injection, it will automatically register a singleton HttpContextAccessor as satisfying the IHttpContextAccessor service. 如果您在Startup.cs中调用了AddIdentity()或在配置依赖项注入的任何位置,它将自动将单例HttpContextAccessor注册为满足IHttpContextAccessor服务的对象。

At this point, in your service layer, you can inject IHttpContextAccessor and retrieve the context from there. 此时,在服务层中,您可以注入IHttpContextAccessor并从那里检索上下文。 This assumes that you understand how the Dependency Injection system works and are using it to instantiate your service layer classes rather than just new ing them. 这是假定您了解如何依赖注入系统的工作原理,并用它来实例化您的服务层类,而不仅仅是new荷兰国际集团他们。

If you want to be able to conveniently access the Id or Name of the ClaimsPrincipal that's exposed in the HttpContext make sure that you import System.Security.Claims so that you have access to the extensions that provide you with the GetUserName() and GetUserId() extension methods. 如果您希望能够方便地访问HttpContext公开的ClaimsPrincipalIdName ,请确保导入System.Security.Claims以便可以访问为您提供GetUserName()GetUserId()扩展方法。

(This is up-to-date as of the beta4 packages that were released with VS2015 RC1) (这是先进的日期作为的beta4包被发布了VS2015 RC1是)

假设您可以在您的层中传递访问服务,则HttpContext.Current的等效项是IHttpContextAccessor.HttpContext ,它是托管层公开的服务。

May be there is better way. 可能有更好的方法。 But for now I am adding a custom middleware as in below code to inject ussername in current thread in startup.cs class. 但是现在,我将在下面的代码中添加一个自定义的中间件,以将ussername注入startup.cs类的当前线程中。 And in the service layer I will read it using Thread.GetData(Thread.GetNamedDataSlot("current-username")). 在服务层中,我将使用Thread.GetData(Thread.GetNamedDataSlot(“ current-username”))读取它。

public class Startup {

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
    {

        //.... code

        app.UseIdentity();

        //... more code

        app.Use(async (ctx, next) =>
        {
            var httpContext = (ctx as HttpContext);
            if (httpContext.User.Identity.IsAuthenticated)
            {
                Thread.SetData(Thread.GetNamedDataSlot("current-username"), httpContext.User.Identity.Name);
            }
            await next();
        });

        //... more code

        app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action}/{id?}",
                    defaults: new { controller = "Home", action = "Index" });
            });

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM