我们可以在 Asp.NET Core 中销毁/无效 JWT 令牌吗?
Posted
技术标签:
【中文标题】我们可以在 Asp.NET Core 中销毁/无效 JWT 令牌吗?【英文标题】:Could we destroy/invalidate JWT token in Asp.NET Core? 【发布时间】:2018-01-26 16:09:01 【问题描述】:我使用 ASP.NET Core 和 ASP.NET Core Identity 来生成 JWT 令牌。
在客户端,我的 React (SPA) 应用调用 API 创建令牌,然后在子请求中包含 Authorization: Bearer
token from API
。
当我想注销时,如何在服务器端立即使令牌失效?
目前,我只是在客户端删除了bear
令牌,并没有包含在下一个请求中?
参考:https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/
Configure
部分中的代码Startup.cs
app.UseJwtBearerAuthentication(new JwtBearerOptions
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = new TokenValidationParameters
ValidIssuer = "MySite",
ValidAudience = "MySite",
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VERYL0NGKEYV@LUETH@TISSECURE")),
ValidateLifetime = true
);
创建令牌的 API
[HttpPost("Token")]
public async Task<IActionResult> CreateToken([FromBody] LoginModel model)
try
var user = await userManager.FindByNameAsync(model.Email);
if (passwordHasher.VerifyHashedPassword(user, user.PasswordHash, model.Password) == PasswordVerificationResult.Success)
var claims = new[]
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Email, user.Email)
;
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VERYL0NGKEYV@LUETH@TISSECURE"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
"MySite",
"MySite",
claims,
expires: DateTime.UtcNow.AddMinutes(45),
signingCredentials: creds);
return Ok(new
Token = new JwtSecurityTokenHandler().WriteToken(token),
Expiration = token.ValidTo,
);
return BadRequest();
catch (Exception ex)
logger.LogError(ex.ToString());
return StatusCode((int)HttpStatusCode.InternalServerError);
【问题讨论】:
【参考方案1】:你不能轻易让它过期,而不会失去它的一些优势或使解决方案变得更加复杂。
最好的办法是使访问令牌时间足够短(
但如果你真的想立即使其失效,你需要做一些事情:
-
创建令牌后缓存令牌的 ID,持续时间与令牌的过期时间(访问令牌和刷新令牌)一样长
[如果Farm/多个实例]需要缓存在分布式缓存中,比如redis
[如果农场/多个实例]您需要通过消息总线(即使用 Redis、RabbitMQ 或 Azure 消息总线)将其传播到应用程序的每个实例,以便它们可以将其存储在本地内存缓存中(因此您不必'不必每次都需要进行网络调用来验证它)
授权时,需要验证ID是否还在缓存中;如果不是,拒绝授权 (401)
当用户注销时,您需要从缓存中删除您的项目。
[如果农场/多个实例]从分布式缓存中删除项目并向所有实例发送消息,以便他们可以将其从本地缓存中删除
其他不需要消息总线/分布式缓存的解决方案将需要在每个请求上联系身份验证服务器,从而扼杀了 JWT 令牌的主要优势。
JWT 的主要优点是它们是自包含的,Web 服务不必调用另一个服务来验证它。它可以通过验证签名在本地进行验证(因为用户不能在不使签名无效的情况下更改令牌)和令牌的到期时间/受众。
【讨论】:
有样品可以参考吗? 您不应在公共客户端中使用刷新令牌。以上是关于我们可以在 Asp.NET Core 中销毁/无效 JWT 令牌吗?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.Net Core:如何获取无效 ModelState 值的键?
ASP.Net Core 3 远程证书在 MacOs 上无效
ASP.NET Core 2.2 - 密码重置在 Azure 上不起作用(无效令牌)
ASP.NET Core 标识 - 无效令牌 (Linux)
asp.net web.Config 配置httpHandlers无效 求解,在线等!
ASP.NET CORE Identity DataProtectionTokenProviderOptions 密码重置令牌无效