JwtBearer TokenValidationParameters 似乎没有经过测试

Posted

技术标签:

【中文标题】JwtBearer TokenValidationParameters 似乎没有经过测试【英文标题】:JwtBearer TokenValidationParameters don't seem to be Tested 【发布时间】:2021-05-01 03:50:11 【问题描述】:

这个问题与 .Net Core API 项目上的 JwtBearer 令牌配置有关。

最近我的一位同事将 Identity Server 4 更新为 v4,因此,提供令牌的方式发生了一些重大变化,最重要的是删除了令牌中的 aud(受众)元素(参考: IDS4 docs)。

建议我在 ASP.Net Core API Startup.cs 中配置以下内容,并添加了对令牌标头(ValidTypes 检查)和密钥的额外检查,这些检查已通过先前使用的 '@987654323 进行了测试@' 配置。

services.AddAuthentication(
        options =>
        
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        
    )
    .AddJwtBearer("Bearer",
        options =>
        
            options.Authority = "https://<<my_identity_server.com>>";
            options.RequireHttpsMetadata = true;

            options.TokenValidationParameters = new TokenValidationParameters()
            
                ValidateAudience = false,
                
                ValidTypes = new[]  "at+jwt" ,
                
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("<<key/secret>>")),
            ;
        );

如果没有这些 TokenValidationParameters 设置,尤其是“ValidateAudience = false”,我会收到与空受众相关的错误(“受众'空'无效”),因此我有信心这些设置正在被读取并应用于在某种程度上。但是,如果我将 正确 预期的标头类型(“at+jwt”)或我的密钥/秘密值更改为 不正确的值,则不会产生错误,并且 API 会继续返回结果调用它。我还尝试添加许多 TokenValidationParameter 设置,例如 ValidateIssuer 和 ValidIssuer 也不会触发不匹配错误。

我遗漏了什么可能会阻止这些项目被正确测试?

【问题讨论】:

ASP.NET Core 因在服务集合和应用程序构建器上调用这些扩展方法时会以各种方式覆盖彼此的配置而出现问题而臭名昭著。听起来您很可能遇到这样的问题,但是如果没有看到您的启动配置,很难知道究竟是什么。顺便说一句,一个已知的“问题”是添加身份(即 AddIdentity() 和 AddDefaultIdentity())会设置授权,因此您必须在这些之后调用自己的 AddAuthentication()。 感谢您的评论@Leaky;发展优先事项意味着我一两天都看不到这个,但我很感激你们的 cmets,很快就会回来。 【参考方案1】:

我相信我已经为触发这个问题的“ValidTypes”值的测试找到了一个相当确凿的答案。答案在updated IDS4 docs找到,里面有评论:

“在 .NET Core 3.1 上,您需要手动引用 System.IdentityModel.Tokens.Jwt Nuget 包 5.6 版才能检查类型标头。”

果然,这是一个 .Net Core 3.1 项目,在安装 System.IdentityModel.Tokens.Jwt 包(当前为 v6.8.0)后,当我预期“错误”时,我可以让测试验证失败TokenValidationParameters 中的值,然后本地日志显示错误,例如:

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7] Bearer was not authenticated. Failure message: IDX10257: Token type validation failed. Type: 'at+jwt'. Did not match: validationParameters.TokenTypes: '*****NOT_MY_JWT_HEADER_TYP*****'.

现在可以将预期的 ValidTypes 更正为 ValidTypes = new[] "at+jwt"

我真的很困惑一个人是如何用中间件来发现这样的东西的;并不是我没有正确版本的软件包……我根本没有安装软件包!我觉得很混乱。

我在问题中还提到,我试图通过为对称密钥值设置 bad 期望来强制失败......但我的 api 调用没有失败。我对此不太确定,但事实证明我的同事已决定更改 JWT 的散列以使用非对称密钥。因此,我推测中间件的某些部分忽略了我设置的 对称 密钥,因为它识别出在令牌上使用了不同类型的算法?

【讨论】:

以上是关于JwtBearer TokenValidationParameters 似乎没有经过测试的主要内容,如果未能解决你的问题,请参考以下文章

36-应用Jwtbearer Authentication

ASP.Net Core 3 API 总是返回 401- JwtBearer

SignalR的JwtBearer认证

包 Microsoft.AspNetCore.Authentication.JwtBearer 5.0.0 与 netcoreapp3.1 不兼容,但它的目标是 net 5.0

带有 rc-1 的 jwtBearer 不记名令牌更新到 ASP.Net 5

ASP.NET Core 中的混合身份验证(Windows 和 AAD JwtBearer)