【问题标题】:Upgrading IdentityServer4 to Core 3.1 - tokens are suddenly not signed correctly?将 IdentityServer4 升级到 Core 3.1 - 令牌突然没有正确签名?
【发布时间】:2020-05-21 14:06:10
【问题描述】:

我们在将 IdentityServer4 (2.5.3 - 3.1.0) 升级到 Core 3.1(从 2.2)时遇到错误。突然发出的令牌没有正确的签名。我们没有改变签名算法;版本之间仍然使用相同的 .PFX 证书。

var idSrvBuilder = services.AddIdentityServer(opts =>
            {
                opts.Events.RaiseErrorEvents = true;
                opts.Events.RaiseFailureEvents = true;
                opts.Events.RaiseInformationEvents = true;
                opts.Events.RaiseSuccessEvents = true;
                if (_env.IsProduction())
                {
                    opts.PublicOrigin = Configuration["Globals:IdentityURL"];
                }
            }).AddSigningCredential(new X509Certificate2(Configuration["Cert:Path"], Configuration["Cert:Password"]));

将 OWIN 中间件“UseIdentityServerBearerTokenAuthentication”用于较旧的 API 时,如果 ValidationModeLocal,但如果它直接针对 IdentityServer 进行验证(使用 ValidationMode ValidationEndpoint)则不会失败。 API 只会返回“未经授权”,但可以使用旧令牌(相同的证书对其进行签名!)

app.UseIdentityServerBearerTokenAuthentication(new IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = AppSettings.Authority,
                ClientId = AppSettings.ApiName,
                ClientSecret = AppSettings.ApiSecret,
                EnableValidationResultCache = false,
                ValidationMode = IdentityServer3.AccessTokenValidation.ValidationMode.Local
            });

看看版本之间发行的令牌有一个明显的区别:

旧的(已移除的有效负载):

eyJhbGciOiJSUzI1NiIsImtpZCI6IjZCMTM4RUIzMUE4OUExQTdEQTdCNkRGNzMwOTRGMzIzREJFNzhCNjYiLCJ0eXAiOiJKV1QiLCJ4NXQiOiJheE9Pc3hxSm9hZmFlMjMzTUpUekk5dm5pMlkifQ.U3unxhW6act8fQLCLAYBJAZ-lIMiKaghVEUdA3b7iM0mI0UqGmYgYw05SvVXTAT8ZNQPuq0D-97d0Z6VVBC2wH7VAl0daF6sYJyuSUEtDiBPttNQ9MsGBNjcN1HABZ0nv-z_lgG2Z9sgp4blCvc7N8xOsja-kuk6m06I7iOfS7O_YKPtTAXA10OCzdtiJbhYijeTFsBJaWf5-J3XJCtqpp-MGXCboE0gQIlvysKz5_CRaaKYptczw-cTX3sgRIhfWn2VxVujhH7JKeSJan52X-fQ4T47PWuVcWNOrcWheeLAbVDQU1U9DiLVVua3BasnIku5Rx4XcLnqCaokCiWZhg

带有以下令牌头:

{
  "alg": "RS256",
  "kid": "6B138EB31A89A1A7DA7B6DF73094F323DBE78B66",
  "typ": "JWT",
  "x5t": "axOOsxqJoafae233MJTzI9vni2Y"
}

新:

eyJhbGciOiJSUzI1NiIsImtpZCI6IjZCMTM4RUIzMUE4OUExQTdEQTdCNkRGNzMwOTRGMzIzREJFNzhCNjYiLCJ0eXAiOiJhdCtqd3QiLCJ4NXQiOiJheE9Pc3hxSm9hZmFlMjMzTUpUekk5dm5pMlkifQ.RmKHRk44c6Ele-VbB8lhNsmmcvKFludaWypuBzQzYqR7AEIuLXAuZ-N4I9ooVvQLHisBJT4qA4epEK9xdtf0ELpcvfEe3Yc2dkJnKp_rjJSRuhqyNHD0hPAoxqVSWHhfaLxLiL7_17mklqLDEqwdXANnA2YCO-Q-9wqGALZorywHYucr0X9m2hYm1oVgXPitG_TAqysYVNnLCHVGZRNE7Xmug0XhkJXzQ8RpZuSHlDHFlT2cgb7psEb4NUfA8v5-q-LyqfPDk4xJZX2ia53SoPpiJbByFgscYF4xk54SkkcB9EOxCCsR-IYHJAmyYkhGRpBVWY5xU_9qb2ioIwkzZg

带有以下标题:

{
  "alg": "RS256",
  "kid": "6B138EB31A89A1A7DA7B6DF73094F323DBE78B66",
  "typ": "at+jwt",
  "x5t": "axOOsxqJoafae233MJTzI9vni2Y"
}

我猜问题是新令牌中的"typ""at+jwt"?那是什么意思?我查看了 IdentityServers 版本、Github 问题、谷歌搜索、stackoverflow,但似乎没有人注意到神秘的新 "at+jwt" "typ"

这会导致问题吗?如何指示我的新版本发布标准 JWT?还有什么奇怪的at+jwt

【问题讨论】:

标签: asp.net-core oauth-2.0 identityserver4 openid-connect


【解决方案1】:

感谢 cmets 中的 @Ruard van Elburg 链接到显式类型标记。

将默认的“at+jwt”更改为“jwt”解决了这个问题:

var idSrvBuilder = services.AddIdentityServer(opts =>
            {
                opts.Events.RaiseErrorEvents = true;
                opts.Events.RaiseFailureEvents = true;
                opts.Events.RaiseInformationEvents = true;
                opts.Events.RaiseSuccessEvents = true;
                opts.AccessTokenJwtType = "jwt";
                if (_env.IsProduction())
                {
                    opts.PublicOrigin = Configuration["Globals:IdentityURL"];
                }
            });

我猜测根本问题在于我们在该 API 中使用的包 IdentityServer3.AccessTokenValidation 无法识别 at+jwt。我们使用它是为了更好地支持引用令牌。

我们也无法将此 API 升级到 ASP Core 并使用来自 Microsoft 的较新的 IdentityServerAuthenticationExtensions,因为我们需要支持来自第三方的一些依赖项。那个包似乎确实能够处理at+jwt 就好了。

编辑:

还是不行。查看了 Ruard 链接到的 Github 问题。

原来我还必须打开 EmitLegacyResourceAudienceClaim,所以看起来不是这样:

var idSrvBuilder = services.AddIdentityServer(opts =>
            {
                opts.Events.RaiseErrorEvents = true;
                opts.Events.RaiseFailureEvents = true;
                opts.Events.RaiseInformationEvents = true;
                opts.Events.RaiseSuccessEvents = true;
                opts.AccessTokenJwtType = "JWT";
                opts.EmitLegacyResourceAudienceClaim = true;
                if (_env.IsProduction())
                {
                    opts.PublicOrigin = Configuration["Globals:IdentityURL"];
                }
            })

【讨论】:

  • 实际上,我怀疑它更深一层。 AccessTokenValidation 包调用JwtFormat 而不指定类型。 JwtFormat 然后设置AuthenticationType parameter 进行验证:_validationParameters.AuthenticationType = "JWT";
  • 看来没有解决。我忘记将 ValidationMode 更改为“Local”或“Both”,我们立即收到“Authorization has been denied for this request”尝试更改签名密钥,也没有成功。
  • 就我而言,这个解决方案奏效了!非常感谢!可以以某种方式将其标记为答案吗?
  • 现在 IdentityServer4 更改为 EmitStaticAudienceClaim 而不是 EmitLegacyResourceAudienceClaim。
猜你喜欢
  • 1970-01-01
  • 2021-10-13
  • 2017-11-19
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 2013-09-30
相关资源
最近更新 更多