Okta 使用 OpenID Connect 配置中的公钥验证 JWT 令牌

Posted

技术标签:

【中文标题】Okta 使用 OpenID Connect 配置中的公钥验证 JWT 令牌【英文标题】:Okta validating JWT token using public keys from OpenID Connect config 【发布时间】:2018-11-11 18:22:48 【问题描述】:

背景

我按照 Okta 的本教程进行操作: https://developer.okta.com/quickstart/#/ios/dotnet/aspnetcore

实现了 Xamarin 的开源 AppAuth.iOS 组件的一个版本,以便能够在 Xamarin.iOS 项目中使用它。 (作品)

创建了一个简单的 asp.net 核心网络服务,如上面文章中所示,并按照说明进行配置。

问题:

我在通过移动应用成功验证后收到一个 JWT 访问令牌,并使用此令牌调用测试 Web 服务。 Web 服务无法验证令牌并显示以下错误消息

错误:

Signature validation failed. Unable to match keys: 'HD3v3KXvARUyg_9i26m2i8itsCY7TpA0-ajhcOsBdkM', token: '"alg":"RS256","typ":"JWT","kid":"HD3v3KXvARUyg_9i26m2i8itsCY7TpA0-ajhcOsBdkM"."ver":1,"jti":"AT.J4uuLmOgCLslqlnUzNbjhw7dzm5KurJVJxHNIXZx-g8.zQJUh4NcHWcIBvdWVLy7fXea4cCoPxv7Avh3+z6PiGM=","iss":"https://dev-111111.oktapreview.com","aud":"https://dev-111111.oktapreview.com","sub":"dsamuylov@111111.com","iat":1527861992,"exp":1527865592,"cid":"0oafa27024puCyvwi0h7","uid":"00uf9rphkt6D8gcXI0h7","scp":["offline_access","openid","profile"]'. at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters) at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()

调试:

在使用 https://jwt.io/ 检查 JWT 令牌后,我发现了用于签署令牌的签名公钥的 kid

然后我去我账户的openid-connect配置 https://dev-111111.oktapreview.com/oauth2/default/.well-known/openid-configuration

找到密钥网址https://dev-111111.oktapreview.com/oauth2/default/v1/keys

那里只列出了 1 个密钥,其 kid 与令牌标头中的不匹配

问题:

如果我为移动客户端和 Web 服务使用相同的 Okta 帐户/服务器,为什么会发生这种情况?这个键不匹配是从哪里来的?

真的希望 Okta 技术团队的某个人能够参与并阐明这一点,因为问题开头链接的引导式演练不起作用。

谢谢,

德米特里

【问题讨论】:

你能检查一下客户端和服务器都配置为使用https://dev-111111.oktapreview.com/oauth2/default/作为发行者/受众吗?如果您缺少oauth2/default,您将遇到此问题 【参考方案1】:

问题原来是配置问题。

在获取令牌的移动客户端中,AppAuth 组件被初始化为issuer 设置为https://dev-111111.oktapreview.com 而不是https://dev-111111.oktapreview.com/oauth2/default 的正确值

这引起了混乱,因为它没有发现 https://dev-111111.oktapreview.com 的 openid-connect 配置失败,而是成功了。它成功的原因是,正如 Okta 支持人员告诉我的那样,它指向 Okta API 的授权服务器,并且出于安全目的,他们将用于 API 令牌的公共签名密钥隐藏起来。这也是签名密钥不同的原因,因为我本质上是指向客户端和后端上的 2 个不同的授权服务器。

如果这个 url 无法检索 openid-connect 配置,或者如果有一些关于两者之间差异的明确文档,我认为它会少得多的混乱。

要实现的另一件事是,Ok​​ta 有 2 个不同的产品,一个基于 IT 的用于管理身份验证的产品和一个以 developer 为中心的产品。除非您购买名为 API Access Management 的附加服务,否则以 IT 为中心的产品不具备此功能,如果您有 developer 版本(管理网站上的深蓝色标题),则默认情况下可在您的帐户中使用。

希望这对将来的某人有所帮助,感谢 Okta 支持团队为我澄清这一点。

【讨论】:

以上是关于Okta 使用 OpenID Connect 配置中的公钥验证 JWT 令牌的主要内容,如果未能解决你的问题,请参考以下文章

使用 .Net Core 中的 PKCE 和 Okta 从 Swagger UI 连接 OpenID

Facebook 的 OpenID Connect 配置

使用 Azure b2c OpenID Connect 配置 Ckan 的身份验证

OpenID Connect 的 Spring Security 5 XML 配置

Passport-OpenID 连接配置

使用 jumbojett/OpenID-Connect-PHP 库的 KeyCloak 身份验证流程