StN*_*las 1 c# authentication jwt asp.net-core
我的应用程序使用cookie和承载身份验证:
var membershipService = configuration.GetValue<string>("MembershipService:BaseUri");
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddCookie()
.AddJwtBearer(opt =>
{
opt.Audience = "gateway";
opt.Authority = membershipService;
opt.RequireHttpsMetadata = false;
opt.SaveToken = true;
opt.Events = new JwtBearerEvents()
{
OnTokenValidated = (context) =>
{
var accessToken = context.SecurityToken as JwtSecurityToken;
if (accessToken != null)
{
ClaimsIdentity identity = context.Principal.Identity as ClaimsIdentity;
if (identity != null)
{
identity.AddClaim(new Claim("access_token", accessToken.RawData));
}
}
return Task.CompletedTask;
}
};
});
Run Code Online (Sandbox Code Playgroud)
当我发送access_token标题时,一切正常.
但是如果我在第二个请求(第一个带有授权头)的头中没有令牌发送,似乎User对先前的身份验证一无所知.即使我这样做HttpContext.SignInAsync("Cookies", User),下一个请求,例如在按下F5之后,也没有用户进行身份验证.
我错过了什么?
首先,除非您实际调用SignInAsynccookie方案,否则不会创建cookie.所以你需要这样做.但仅仅因为用户发送cookie并不意味着cookie方案将运行并尝试对用户进行身份验证.
你这样打电话AddAuthentication:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
Run Code Online (Sandbox Code Playgroud)
这意味着JWT承载认证将是默认的认证方案.因此,当身份验证中间件运行时,它将尝试验证该身份验证方案,并且仅对此进行身份验证.如果您有多个身份验证方案,则只有默认身份验证方案才会实际尝试对用户进行身份验证.否则,如果多个方案可以验证用户,则会发生冲突.
因此,在您的情况下,用户未经过身份验证,因为cookie身份验证方案根本没有运行.你应该考虑你的默认方案应该是什么.如果您只想将承载令牌用作"登录",则使用cookie身份验证方案作为默认值是有意义的.然后,您可以提供需要承载方案的登录操作,然后在cookie方案中签名:
[Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]
public async Task<IActionResult> Login()
{
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, User);
return View();
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用您access_token的Authorize属性调用该路由,并使该属性触发JWT承载方案的身份验证,并使用该用户使用cookie方案登录.因此后续请求将使用cookie方案(作为默认值)并且将识别用户.
最后请注意,JWT承载认证通常被视为无状态认证方法,并且在每个请求上明确发送令牌被认为是正确的做法.因此,从中生成一个cookie会有点奇怪.
| 归档时间: |
|
| 查看次数: |
715 次 |
| 最近记录: |