【问题标题】:Does AddJwtBearer() Do what I think it does?AddJwtBearer() 做我认为的事情吗?
【发布时间】:2019-11-07 23:14:22
【问题描述】:

我正在尝试确定 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-core keycloak


    【解决方案1】:

    我也想知道 - 研究/调试表明 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。意味着没有理由添加权限。

    【讨论】:

    • 我最终为该权限设置了一个 Charles 代理,并验证它会发出所有适当的调用,但不是在启动时,在第一次请求时!然后每次传递无效令牌时,它都会检查它以查看权限是否更改了密钥
    • 大家好,如果我们开始“逆向工程”它,您是否看到/知道 jwks 端点响应是否缓存?例如在 nodeJs 中,类似的中间件(node-jsonwebtoken 和 node-jwks-rsa)有缓存选项,比如缓存年龄等。我相信 JwtBearer 应该有类似的,但看不到配置它的选项..
    • 这个答案中有一些非常有价值的情报,在 MSDN 文档中全部省略了......
    【解决方案2】:

    您不需要设置 TokenValidationParameters 。如果 Authority 是颁发令牌的身份验证服务器的地址设置正确,JWT 不记名中间件将使用此 URI 查找和检索可用于验证令牌签名的公钥。它还将确认令牌中的 iss 参数与此 URI 匹配。中间件将帮助从 OIDC 元数据中获取密钥并缓存密钥。

    TokenValidationParameters 可用于您想要验证令牌而不访问发行服务器的情况。相反,您想使用本地已经存在的公钥来验证传入的令牌。然后您不能设置Authority,设置ValidateIssuerSigningKeyValidateIssuer,最后设置IssuerSigningKey,这是使用的公钥用于验证传入的 JWT 令牌。

    【讨论】:

    • 虽然这主要回答了我的问题。同样,这一切似乎都是抽象的。 .net core 3.0 中不再有 jwtbearer 的中间件配置。这还在发生吗?
    • “.net core 3.0 中没有 jwtbearer 的中间件配置”是什么意思?配置与.net core 2.2 相同,source codes 可供您使用。如何验证 jwt 令牌不会改变 AFAIK。
    【解决方案3】:

    查看AddJwtBearer 的源代码,根据我的实验,Authority 只是您需要分配的属性。在这种情况下,处理程序将使用

    MetadataAddress = $"{Authority}/.well-known/openid-configuration";
    

    为您的领域解析元数据 URL 并从那里下载签名密钥。

    【讨论】:

      【解决方案4】:

      您可以参考https://zhiliaxu.github.io/how-do-aspnet-core-services-validate-jwt-signature-signed-by-aad.html#configuration了解AddJwtBearer()如何从.well-known/openid-configuration获取非对称签名密钥。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 2012-07-04
        • 1970-01-01
        • 2010-12-17
        • 2016-03-19
        • 1970-01-01
        相关资源
        最近更新 更多