1

我有一个oauth2资源服务器,它使用JwtBearerMiddleware来验证访问令牌。现在我不希望安全印记发生变化时访问令牌无效。因为它看起来像这个中间件不会自己验证安全印章。jwtBearerMiddleware中的安全戳验证程序

我发现SecurityStampValidator类似乎只验证cookie身份验证。

我在哪里以及如何从我的json Web令牌验证安全印章?


我目前的方式做到这一点的是当我注册JwtBearerMiddleware以注册OnTokenValidated事件的事件处理程序。在这个事件处理程序中,我简单地查询数据库中的安全声明并将其与令牌中的声明进行比较。当安全戳不相同时,我只需将上下文的TicketSecurityToken设置为null,并跳到下一个中​​间件,如果需要身份验证,它将最终抛出401 http状态码。

app.UseJwtBearerAuthentication(new JwtBearerOptions 
{ 
    ... 
    Events = new JwtBearerEvents 
    { 
     OnTokenValidated = async (ctx) => 
     { 
      var securityStampClaim = ctx.Ticket.Principal.Claims.FirstOrDefault(claim => claim.Type == "AspNet.Identity.SecurityStamp"); 
      var subjectClaim = ctx.Ticket.Principal.Claims.FirstOrDefault(claim => claim.Type == OpenIdConnectConstants.Claims.Subject); 

      if (securityStampClaim == null || subjectClaim == null) 
       return; 

      var user = await userStore.FindByIdAsync(subjectClaim.Value, ctx.HttpContext.RequestAborted); 
      if (user?.SecurityStamp == securityStampClaim.Value) 
       return; 

      ctx.SecurityToken = null; 
      ctx.Ticket = null; 
      ctx.SkipToNextMiddleware(); 
     } 
    } 
}); 

这是应该怎么做?

回答

1

这是应该怎么做?

技术上,是的(你甚至可以用SignInManager.ValidateSecurityStampAsync(principal)来简化你的代码)。

这就是说,你应该认真考虑避免存储安全邮票在JWT令牌,因为它们不是用来确定令牌或cookie是否应被视为已撤销,他们也用只是“不透明”的字符串作为ASP.NET Core Identity生成2FA令牌熵的唯一来源:如果您将它们按原样存储在JWT中,则可以通过恶意的第三方客户端应用程序轻松提取它们,并用于预测有效的2FA代码登录用户。

这是一个已知问题,但AFAIK,没有计划解决它:https://github.com/aspnet/Identity/issues/626

如果要将安全标记存储在访问令牌中,请考虑使用OpenIddict的默认(加密)格式,该格式与ASP.NET Core对其加密的身份验证Cookie使用的格式完全相同。

+0

为什么asp身份证在理赔原则中存储安全戳呢? 并且用每个验证邮票的请求来访问数据库效率不高吗? –