【问题标题】:Identity Server 4 issued JWT Validation failureIdentity Server 4 发出 JWT 验证失败
【发布时间】:2018-07-23 18:50:19
【问题描述】:

我有一个基于 IdentityServer 4 (.Net Core v2) 运行的 Identity Server,目标是完整的 .Net 框架,并且我有一个针对 ASP.Net Web API 2(即 NOT .Net Core)构建的 ASP.NET WebAPI正在使用 Identity Server 3 OWIN 中间件进行令牌身份验证。

在本地运行时,一切正常 - 我可以使用 Postman 使用 RO 密码流从身份服务器请求访问令牌,然后我可以向 WebAPI 发出请求,将令牌作为不记名令牌发送 - 所有工作正常。

现在,当一切都托管在我们的测试服务器上时,我在调用 WebAPI 时遇到了问题 - 我只是收到了未经授权的响应。从身份服务器返回的令牌没有问题(使用 http://jwt.io 检查),但在 WebAPI 中验证 JWT 失败。 在进一步调查中,添加 Katana 日志记录后,我看到正在报告 SecurityTokenInvalidAudienceException。

观众验证失败。观众: 'https://11.22.33.44:1234/resources,XXXWebApi'。不匹配: 验证参数.ValidAudience: 'https://localhost:1234/resources' 或 validationParameters.ValidAudiences: 'null'

看看智威汤逊的观众,我们有:

aud: "https://11.22.33.44:1234/resources", "XXXWebApi"

在 WebAPI 启动中,我调用了

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = , // path to our local ID Server
            ClientId = "XXXWebApi",
            ClientSecret = "XXX_xxx-xxx-xxx-xxx",
            RequiredScopes = new[] { "XXXWebApi" }
        });

所以 JWT 受众看起来不错,但它显然与中间件提供的内容不匹配(从 IdP 发现端点构建)。我会认为是因为我指定了RequiredScopes 以包含足以匹配JWT 受众的XXXWebApi,但这似乎被忽略了。

我不确定要在 WebAPI 身份验证选项中进行哪些更改才能使其正常工作。

编辑:我更改了 WebAPI 令牌身份验证选项以使用验证端点,这在 IdentityServer 中也失败并出现相同的错误。 如果我使用相同的令牌直接从 Postman 调用 Identity Server 自省端点,它会成功。

【问题讨论】:

  • 您是否确认两个地方的代码完全一样?你检查过网址吗?他们一切都好吗?
  • 是的,我直接从 VStudio 中发布代码,部署到服务器并更改配置文件中的 url 以确保它们指向 Identity Server 的正确端口。如果我从邮递员单独调用令牌自省端点,那么令牌验证就好了。问题只是 IdentityServer OWIN 中间件中令牌的自动验证,但我不知道如何修复它
  • 您是否使用 IdSrv3 来验证您从 IdSrv4 获得的 JWT?
  • 服务器是Identity Server 4,我在WebAPI中使用IdentityServer3.AccessTokenValidation,这是IdServer团队创建的中间件。所以它不完全是 IdentityServer 3,它只是 OWIN 中间件,所以它应该与使用的目标 Identity Server 版本无关。
  • @MarkBennetts 你最终解决了这个问题吗?我也在苦苦挣扎,还没有找到任何解决方案。

标签: jwt identityserver4 identityserver3 owin-middleware


【解决方案1】:

据我了解,您的 WebAPI 项目被用作 API 资源。

如果是这样 - 从UseIdentityServerBearerTokenAuthentication 中删除“clientId”和“clientSecret”,保留“RequiredScopes”和权限(您可能还需要设置ValidationMode = ValidationMode.Both)。

当您使用参考令牌时,您需要它们。从你所说的 - 你正在使用 JWT 一个。检查hereherehere

【讨论】:

  • 好的,我今天不在办公室,所以我会尝试删除 ClientID 和 Secret,尽管我不明白为什么这会对 JWT 验证产生影响。验证模式默认为 Both,我将其更改为 Local 以确保在 IDP 验证被尝试但失败时执行本地验证(它不是,所以我也会恢复它)。
  • 好吧,因为我怀疑这没什么区别 - 在 JWT 的本地验证期间不使用 ClientID 和 Secret,所以无论我是否提供它们都没有区别。
【解决方案2】:

好的,所以经过大量的挠头和尝试各种事情后,我至少有一些工作。

我必须确保 Identity Server 是针对公开可用的 DNS 托管的,并在 IdentityServerBearerTokenAuthenticationOptions 中配置授权值以使用相同的值。

这样,任何颁发的令牌在 JWT 受众 (aud) 中都具有 xx.yy.zz 完整域名,并且当 WebAPI 中的 OWIN 验证中间件验证 JWT 时,它使用相同的地址而不是 localhost 进行比较。

我仍然有点困惑,为什么中间件不能只使用范围值进行验证,因为令牌是在受众中使用 API 资源范围 (XXXWebAPi) 发出的,并且 API 在如图所示。

【讨论】:

  • 您可以在 tokenvalidationparameters 中设置相关的委托,并根据需要自定义默认是否同时检查。
猜你喜欢
  • 2019-04-18
  • 2017-09-21
  • 2020-10-20
  • 2022-01-14
  • 2018-12-03
  • 1970-01-01
相关资源
最近更新 更多