实体框架核心DbContext中的用户主体

时间:2018-11-01 19:31:50

标签: asp.net-mvc entity-framework asp.net-core entity-framework-core

我正在将项目从.NET 4.6升级到.NET Core。它是具有使用EntityFramework的WebAPI的ASP.NET MVC网站。当(MVC或WebAPI)控制器启动DbContext时,有一些代码需要将用户标识为ClaimsIdentity来检查其声明。在以前的.NET中,像这样在Thread.CurrentPrincipal上最可靠地可用:

ClaimsIdentity identity = System.Threading.Thread.CurrentPrincipal.Identity as ClaimsIdentity;

IIRC,这是最安全的方法,因为您可能来自不同的上下文-WebAPI或ASP.NET MVC。

在.NET核心解决方案中,我尝试将Dependency注入IHttpContextAccessor到构造函数中,但是HttpContext上的User未获得授权并且没有声明

ClaimsIdentity identity = httpContext.HttpContext.User.Identity;
// identity.IsAuthenticated == false. identity.Claims is empty.

在Startup.cs中连接了安全性:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).
                AddCookie(options =>
                {
                    options.LoginPath = "/Login";
                    options.Cookie.HttpOnly = true;
                }).
                AddJwtBearer(options =>
                {
                    options.RequireHttpsMetadata = false;
                    options.SaveToken = true;

                    var key = Configuration["Tokens:Key"];

                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidIssuer = Configuration["Tokens:Issuer"],
                        ValidAudience = Configuration["Tokens:Issuer"],
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
                    };
                });

用户在/ Login MVC视图页面上登录,该页面通过Cookies登录,并在另一个保存在客户端的请求中生成Bearer令牌。完成所有这些操作后,用户将被重定向到主页。

Cookie登录:

    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = bIsPersistent });

令牌生成(从ajax调用,在重定向之前已保存到本地存储)

var secretKey = Configuration["Tokens:Key"];
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var creds = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256 );
var expires = DateTime.Now.AddHours(8);
var token = new JwtSecurityToken(
    _config["Tokens:Issuer"],
    _config["Tokens:Issuer"],
    oAuthIdentity.Claims,
    expires: expires,
    signingCredentials: creds
    );

ret = Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });

登陆到主页后,使用承载令牌对WebApi进行ajax调用(我将承载令牌从http请求中拉出并验证了jwt.io上的签名),并且webapi导致DbContext为实例化,这就是身份无效的地方。

好像身份没有正确地编组到DbContext-

如何在DbContext中获得正确的用户或身份?

此外,在这一点上我需要它在DbContext构造中,我对依赖注入没有很多控制权。但是我基本上需要从默认构造函数中获取此信息,或者以某种方式延迟加载它。

1 个答案:

答案 0 :(得分:0)

使用您的设置,您有两个身份验证设置。因此,在Startup类的ConfigureServices函数中,您需要使用如下代码:

services.AddAuthentication().AddCookie().AddJwtBearer();

请不要忘记指定默认身份验证。例如,如果您希望身份验证默认为cookie,则可以使用以下方法:

services.AddAuthentication("Cookies").AddCookie().AddJwtBearer();

或者为了保持代码的安全性,

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie().AddJwtBearer();

在启动类的Configure函数中,不要忘记添加

app.UseAuthentication();

在控制器内进行身份验证时,如果不使用默认方案,则需要与[Authorize]一起使用方案名称。

[Authorize(AuthenticationSchemes = "")]