如何在 .NET Core 中为 JWT 令牌设计自定义验证器?
Posted
技术标签:
【中文标题】如何在 .NET Core 中为 JWT 令牌设计自定义验证器?【英文标题】:How to design a custom validator for JWT tokens in .NET Core? 【发布时间】:2019-12-03 01:16:24 【问题描述】:我正在使用如下身份验证。
TokenValidationParameters parameters = new TokenValidationParameters
ValidateIssuerSigningKey = false,
ValidateLifetime = true,
ValidateActor = false,
ValidateAudience = false,
ValidateIssuer = false,
ValidateTokenReplay = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(...)),
ClockSkew = TimeSpan.Zero
;
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.TokenValidationParameters = parameters;
options.SecurityTokenValidators.Add(new SecurityTokenValidator());
);
我已经实现了 ISecurityTokenValidator (Microsoft.IdentityModel.Tokens) 并像这样覆盖了 ValidateToken 方法。
public ClaimsPrincipal ValidateToken(string securityToken,
TokenValidationParameters parameters,
out SecurityToken token)
IIdentity identity = new ClaimsIdentity(new[] new Claim("name", "donkey") );
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
token = new JwtSecurityToken();
return principal;
代码之前授权正确,但现在,我指定了一个自定义验证器,我只得到 401 Unauthorized。很明显,我在这里做错了什么,主要嫌疑人是 token,即sparsely documented。
调试的时候,可以看到传入的token的内容,但是由于参数是out,所以不得不赋值,编译器拒绝配合。
-
验证失败是因为过期的令牌是虚拟的吗?
返回 bool 导致 401 出现的方法在哪里?
返回一组声明和经过验证的令牌有什么意义?
我一直在谷歌搜索,但未能找到这方面的具体信息。这一切都淹没在大量博客相互复制示例的噪音中(我可能不知道正确的搜索条件)。
有一些示例,例如 this 和 this,但由于复杂性,我不确定它是否适合遵循。其他人似乎只是在重用 JwtSecurityTokenHandler 的一个实例,这似乎不是我想要的自定义验证器。
【问题讨论】:
您使用的是哪个版本的 ASP.NET Core? Core 1 和 Core 2 的身份验证设计非常不同。另外,您是否遇到编译器错误或运行时问题?参数名称为token
,但您的代码示例正在分配 validatedToken
。
@Dai 添加了 Core 2.2 的标签并更正了错字(当我为更好的显示进行格式化时出错了)。
能否请您在Startup
课堂上发布您的AddAuthentication
部分?
另外,您使用的是哪个ISecurityTokenValidator
?它位于多个命名空间中,例如 System.IdentityModel
、Microsoft.IdentityModel
等。
@Dai 好吧,我会被诅咒的 - 这是非常出乎意料的。否则我会在问题中提到这一点。它是 Microsoft.IdentityModel.Tokens;。我认为它们有所不同?
【参考方案1】:
您实际上是在谈论 2 个不同的部分,身份验证(证明您是谁)和授权(您可以做什么)。
为了认证,
401 可能是由于未设置 ValidFrom
和 ValidTo
属性引起的。它们在构造函数中设置。您还可以将 TokenValidationParameters
上的 ValidateLifetime
属性设置为 false 以绕过它。
以下是使用构造函数的示例: https://github.com/aspnet/AspNetCore/blob/c76cb9248de8966b25bc08b098b88d6734b96d09/src/Mvc/test/WebSites/SecurityWebSite/BearerAuth.cs#L38
我相信401
重定向是在AuthenticationHandler
的HandleChallengeAsync
方法中完成的
这是那个方法:
https://github.com/aspnet/AspNetCore/blob/c76cb9248de8966b25bc08b098b88d6734b96d09/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs#L195
这是身份验证/授权的灰色区域。我心目中的 401 将是身份验证,而 403 将是授权。关于是否返回401
挑战响应和403
禁止响应的决定我很确定是在PolicyEvaluator
中的AuthorizeAsync
方法中完成的。
https://github.com/aspnet/AspNetCore/blob/6526022f6c72eb98e9afb7dd77672c4340f00312/src/Security/Authorization/Policy/src/PolicyEvaluator.cs#L77
希望对你有帮助。
声明集由策略评估者用于授权。
https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2
【讨论】:
我不确定我是否明白第一个链接的意思。令牌返回那里 - 它有什么用?我知道令牌在 ValidateToken 中已过期,但我根本不明白为什么。令牌(字符串形式)已经在框架中可用。是否需要进入(字符串)令牌,向其添加 som 声明并返回它的新更新版本?以上是关于如何在 .NET Core 中为 JWT 令牌设计自定义验证器?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ASP.NET Core 中转储解析的 JWT 令牌?
如何使用 JWT 令牌在 .NET Core API 中检索当前用户数据?
如何在 asp.net core 中设置 jwt 令牌的生命周期
如何在 Dot Net Core 中使用 JWKS 验证 JWT 令牌