如何在 .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 令牌设计自定义验证器?的主要内容,如果未能解决你的问题,请参考以下文章