jwtBearerMiddleware 中的安全标记验证器
Posted
技术标签:
【中文标题】jwtBearerMiddleware 中的安全标记验证器【英文标题】:Security stamp validator in jwtBearerMiddleware 【发布时间】:2017-09-03 00:54:54 【问题描述】:我有一个 oauth2 资源服务器,它使用 JwtBearerMiddleware
来验证访问令牌。现在,如果安全标记已更改,我不希望访问令牌无效。看起来这个中间件本身并没有验证安全标记。
我发现 SecurityStampValidator
类似乎只验证 cookie 身份验证。
我必须在哪里以及如何验证来自我的 json Web 令牌的安全标记?
我目前的做法是在注册JwtBearerMiddleware
时为OnTokenValidated
事件注册一个事件处理程序。在这个事件处理程序中,我只需在数据库中查询安全声明并将其与令牌中的声明进行比较。当安全标记不相同时,我只需将上下文的Ticket
和SecurityToken
设置为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 的格式完全相同。
【讨论】:
那么为什么asp identity 会在Claims 原则中存储Security stamp?每次请求验证印章时都访问数据库不是很有效吗? 注意:上述问题已在 2.1.0 中修复 那么现在将它添加到 jwt 令牌中是否安全? 如果您的 JWT 令牌未加密(通常使用 JWE)或者如果您不拥有使用它们的资源服务器,那么不,这不安全。 ASP.NET 团队打开了一张单独的票,考虑在未来的版本中修复它,但它在积压中,所以很可能在一段时间内不会修复:github.com/aspnet/AspNetCore/issues/5772 @NtFreX “现在返回应该是安全的”......我不同意:1)即使在加密场景中,GUID 也保证有足够的熵来使用这一事实绝对不是新的(它是2015 年已经如此)。 2) TOTP 仍然使用安全标记:如果您不保密,您的应用程序将处于危险之中。以上是关于jwtBearerMiddleware 中的安全标记验证器的主要内容,如果未能解决你的问题,请参考以下文章