在asp.net mvc 6(vNext)中Thread.CurrentPrincipal Identity.Name为null

时间:2015-04-16 14:39:19

标签: c# asp.net-mvc asp.net-core asp.net-core-mvc

我正在使用Asp.Net MVC6(vNext),Identity 3.0。* beta3开发Web应用程序。这是具有UI,服务和数据库的3层应用程序。我可以使用SignInManager类Asp.net身份登录用户,我正在尝试使用角色&声明在服务层中,以便我可以验证用户是否有权采取某些操作。

我们如何从服务层中的当前请求主体标识获取当前用户名。在MVC 5中,我使用Thread.CurrentPrincipal来执行此操作。但是在MVC6中,Identity.Name的{​​{1}}被设置为null。

有人能告诉我怎么做吗?另外,如果您有更好的解决方案,请告诉我。

3 个答案:

答案 0 :(得分:3)

如果您在Startup.cs中或在配置依赖项注入的任何地方调用AddIdentity(),它将自动注册单个HttpContextAccessor以满足IHttpContextAccessor服务。< / p>

此时,在您的服务层中,您可以注入IHttpContextAccessor并从那里检索上下文。这假定您了解依赖注入系统如何工作并使用它来实例化您的服务层类而不仅仅new它们。

如果您希望能够方便地访问Id中公开的Name的{​​{1}}或ClaimsPrincipal,请确保导入{ {1}}以便您可以访问为您提供HttpContextSystem.Security.Claims扩展程序的扩展程序。

(这是VS2015 RC1发布的GetUserName()软件包的最新版本)

答案 1 :(得分:2)

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

答案 2 :(得分:1)

可能有更好的方法。但是现在我正在添加一个自定义中间件,如下面的代码,在startup.cs类的当前线程中注入ussername。在服务层,我将使用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" });
            });

    }
}