我们可以在 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 密码重置令牌无效