Okta 使用来自 OpenID Connect 配置的 public 密钥验证 JWT 令牌
Okta validating JWT token using public keys from OpenID Connect config
背景
我遵循了 Okta 的教程:
https://developer.okta.com/quickstart/#/ios/dotnet/aspnetcore
实施了来自 Xamarin 的开源 AppAuth.iOS 组件的一个版本,以便能够在 Xamarin.iOS 项目中使用它。 (作品)
创建了一个简单的 asp.net 核心 web-service,如上文所述,并按照说明进行了配置。
问题:
通过移动应用程序成功验证后,我收到一个 JWT 访问令牌,并使用此令牌调用测试 web-service。 Web-service 验证令牌失败并出现以下错误消息
错误:
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 令牌后,我发现用于签署令牌的签名 public 密钥的 kid
然后我去我账户的 openid-connect 配置
https://dev-111111.oktapreview.com/oauth2/default/.well-known/openid-configuration
找到钥匙urlhttps://dev-111111.oktapreview.com/oauth2/default/v1/keys
那里只列出了 1 个密钥,它的 kid
与令牌中的密钥不匹配 header
问题:
如果我对移动客户端和 web-service 使用相同的 Okta account/server,为什么会发生这种情况?这个密钥不匹配是从哪里来的?
真的希望 Okta 技术团队的某个人可以权衡并阐明这一点,因为照原样,问题开头链接的指导演练不起作用。
谢谢,
德米特里
原来是配置问题。
在获取令牌的移动客户端中,AppAuth 组件初始化为 issuer
设置为 https://dev-111111.oktapreview.com
而不是 https://dev-111111.oktapreview.com/oauth2/default
的正确值
这引起了混乱,因为它没有在 https://dev-111111.oktapreview.com
处发现 openid-connect 配置失败,而是成功了。它成功的原因是因为正如 Okta 支持人员告诉我的那样,它指向 Okta API 的授权服务器并且他们保留 public 用于隐藏 API 令牌的签名密钥安全目的。这也是签名密钥不同的原因,因为我实际上是在客户端和后端指向 2 个不同的授权服务器。
如果这个 url 无法检索 openid-connect 配置,或者如果有一些关于两者之间差异的明确文档,我认为它会减少很多混淆。
另一件需要注意的事情是,Okta 有 2 种不同的产品,一种是基于 IT
的用于管理身份验证的产品,另一种是以 developer
为中心的产品。以 IT
为中心的产品没有此功能,除非您购买了名为 API Access Management
的附加服务,如果您有 developer
版本(管理网站上的深蓝色 header ) 这在您的帐户中默认可用。
希望这对以后的人有所帮助,感谢 Okta 支持团队为我澄清这一点。
背景
我遵循了 Okta 的教程: https://developer.okta.com/quickstart/#/ios/dotnet/aspnetcore
实施了来自 Xamarin 的开源 AppAuth.iOS 组件的一个版本,以便能够在 Xamarin.iOS 项目中使用它。 (作品)
创建了一个简单的 asp.net 核心 web-service,如上文所述,并按照说明进行了配置。
问题:
通过移动应用程序成功验证后,我收到一个 JWT 访问令牌,并使用此令牌调用测试 web-service。 Web-service 验证令牌失败并出现以下错误消息
错误:
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 令牌后,我发现用于签署令牌的签名 public 密钥的 kid
然后我去我账户的 openid-connect 配置 https://dev-111111.oktapreview.com/oauth2/default/.well-known/openid-configuration
找到钥匙urlhttps://dev-111111.oktapreview.com/oauth2/default/v1/keys
那里只列出了 1 个密钥,它的 kid
与令牌中的密钥不匹配 header
问题:
如果我对移动客户端和 web-service 使用相同的 Okta account/server,为什么会发生这种情况?这个密钥不匹配是从哪里来的?
真的希望 Okta 技术团队的某个人可以权衡并阐明这一点,因为照原样,问题开头链接的指导演练不起作用。
谢谢,
德米特里
原来是配置问题。
在获取令牌的移动客户端中,AppAuth 组件初始化为 issuer
设置为 https://dev-111111.oktapreview.com
而不是 https://dev-111111.oktapreview.com/oauth2/default
这引起了混乱,因为它没有在 https://dev-111111.oktapreview.com
处发现 openid-connect 配置失败,而是成功了。它成功的原因是因为正如 Okta 支持人员告诉我的那样,它指向 Okta API 的授权服务器并且他们保留 public 用于隐藏 API 令牌的签名密钥安全目的。这也是签名密钥不同的原因,因为我实际上是在客户端和后端指向 2 个不同的授权服务器。
如果这个 url 无法检索 openid-connect 配置,或者如果有一些关于两者之间差异的明确文档,我认为它会减少很多混淆。
另一件需要注意的事情是,Okta 有 2 种不同的产品,一种是基于 IT
的用于管理身份验证的产品,另一种是以 developer
为中心的产品。以 IT
为中心的产品没有此功能,除非您购买了名为 API Access Management
的附加服务,如果您有 developer
版本(管理网站上的深蓝色 header ) 这在您的帐户中默认可用。
希望这对以后的人有所帮助,感谢 Okta 支持团队为我澄清这一点。