首页 > 解决方案 > AddJwtBearer() 做我认为的事情吗?

问题描述

我正在尝试确定 JwtBearer 服务是否为 .net core 3.0 提供,它实际上是否使用了我的 oidc 提供商众所周知的配置提供的不对称签名密钥???

我找不到与此相关的任何文档。

.AddJwtBearer(opt =>
                    {
                        opt.Authority = "http://localhost:8180/auth/realms/master";
                        opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                        {
                            ValidateIssuer = true,
                            ValidateAudience = false,
                            ValidateLifetime = true,
                            ValidateIssuerSigningKey = true
                        };

我使用 Keycloak 4.8.3 作为我的 oidc 提供程序。我能找到的最接近的文档在这里。https://developer.okta.com/blog/2018/03/23/token-authentication-aspnetcore-complete-guide

相关文章在这里:

如果您通过发现文档让 JwtBearer 中间件自动配置,这一切都会自动运行!

上面的代码是否做到了所有这些?这在 3.0 中是否仍然相关,因为我们不再注册中间件?

我敢打赌,很多人不知道不对称签名密钥,以及它们为何如此重要。我们已经从开发人员那里抽象了很多东西,现在我什至不知道我的 api 是否安全。

所以最后一个问题是。Does the .AddJwtBearer service with "ValidateIssuerSigningKey" periodically check the wellknown or whatever discovery document to grab the latest asymettric signing key?

标签: asp.net-core.net-corekeycloak

解决方案


我也想知道 - 研究/调试表明 JwtBearer 确实试图联系当局以获取公钥。

这是验证期间调用的函数:

// System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.cs

protected virtual SecurityKey ResolveIssuerSigningKey(string token, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
            {
                if (validationParameters == null)
                    throw LogHelper.LogArgumentNullException(nameof(validationParameters));

                if (jwtToken == null)
                    throw LogHelper.LogArgumentNullException(nameof(jwtToken));

                return JwtTokenUtilities.FindKeyMatch(jwtToken.Header.Kid, jwtToken.Header.X5t, validationParameters.IssuerSigningKey, validationParameters.IssuerSigningKeys);
            }

显然,仅当您在配置中设置 Oauth 权限时,才会调用这种与公钥联系权限的逻辑:

 .AddJwtBearer(o =>{
     o.Authority = "https://authorityUri/";
 })

AddJwtBearer 中间件处理程序内部将添加“.well-known/openid-configuration”字符串到 o.Authority 并尝试获取包含授权服务器详细信息的 JSON。(谷歌示例:https ://accounts.google.com/.well-known/openid-configuration )。

下一步 - 获取jwks_uri(如果是 google https://www.googleapis.com/oauth2/v3/certs)并获取 jwks 文件,该文件将包含用于签名验证的数据(公钥、算法、初始向量)..

在所有这些步骤之后,JwtBearer 验证令牌签名。

仅供参考 - 如果您使用自己的签名密钥颁发者配置它,JwtBearer 可以在没有权限的情况下验证令牌,如下所示:

.AddJwtBearer(o =>{
         o.TokenValidationParameters.IssuerSigningKey = GetKey();
         //in this case you need to provide valid audience or disable validation
         o.TokenValidationParameters.ValidateAudience = false
         //in this case you need to provide valid issuer or disable validation
         o.TokenValidationParameters.ValidateIssuer= false
     })

Microsoft.IdentityModel.Tokens.SecurityKey = GetKey(){
            var key = "Secret_Pass";
            return new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
}

在这种情况下,您需要提供颁发者和受众或禁用验证。此配置可用于 B2B 案例 - 服务器到服务器通信 - 当您没有 Oauth 服务器并使用共享密钥自己发布令牌时。

有关全貌,请查看此配置 - 权限和颁发者密钥集:

 .AddJwtBearer(o =>{
     o.Authority = "https://authorityUri/";
     o.TokenValidationParameters.IssuerSigningKey = GetKey();
 })

在这种情况下,权限不会被触及,您本地生成的密钥将用于验证令牌,因此优先级是 TokenValidationParameters.IssuerSigningKey。意味着没有理由添加权限。


推荐阅读