刷新的 OAuth2 令牌具有无效签名 (Azure AD OAuth2)
Posted
技术标签:
【中文标题】刷新的 OAuth2 令牌具有无效签名 (Azure AD OAuth2)【英文标题】:Refreshed OAuth2 token has invalid signature (Azure AD OAuth2) 【发布时间】:2018-11-27 05:50:24 【问题描述】:我正在尝试创建一个身份验证流程,其中用户的访问令牌与刷新令牌一起保存在服务器端会话中,当令牌过期时,如果会话仍然有效,它会被更新。但是,在使用与原始令牌相同的方法进行验证时,刷新后我从 Azure AD 返回的令牌具有无效签名。
这是一个说明问题的可运行要点:https://gist.github.com/tlycken/fdaf47dc31e03de43a1a07fbbea2ab91
我所做的基本上是这样的:
当用户请求页面时,检查会话。如果不存在,则重定向到/auth
,该/auth
将重定向到 Azure AD,当我返回时,我有一个有效的令牌存储在会话中。
使用jwks-rsa
验证会话中的令牌。 (这通常工作正常,所以我特意在令牌字符串中添加一些内容,以使测试代码中的签名无效。)
如果令牌验证失败,并且会话中有刷新令牌,请尝试使用该刷新令牌获取新令牌。此请求通常返回状态为200 OK
和一组新的访问/刷新令牌。
使用与验证旧访问令牌相同的代码验证新访问令牌(现在不会弄乱令牌)。 这应该可以,IIUC,但它失败并出现错误 invalid signature
。
为什么我新刷新的令牌没有通过验证?
更新: 我能够创建一个更简单的流程来重现它;要点已更新。它现在执行以下操作(一路打印这些消息):
no session, redirecting to /auth
successful auth callback, redirecting to /
verifying old token
decoded user id e7f02a6e-510c-430d-905c-f8a0e63206c2
refreshing
fetching /me with renewed token
got user id e7f02a6e-510c-430d-905c-f8a0e63206c2
verifying new token
token verification failed: invalid signature
除了自己验证令牌之外,我现在还使用它向 Azure 发送请求,希望这样的请求会因无效令牌而失败。但它通过了!
【问题讨论】:
我的猜测是刷新的访问令牌没有签名。你能验证一下吗? 刷新后的token由.
分隔的三部分组成,IIUC最后是签名(第一部分是header和payload)。如果我只解码标题,我会得到以下信息, "typ": "JWT", "nonce": "AQABAAAAAADX8GCi6Js6SK82TsD2Pb7rCCqFemr3qpUpj3EJja8SpJatcDYA51CdCJueMlRpYfOo8_wofd4aSRhZ4EX0MWALK62rwaGf8oDPsIB9rXCRyiAA", "alg": "RS256", "x5t": "TioGywwlhvdFbXZ813WpPay9AlU", "kid": "TioGywwlhvdFbXZ813WpPay9AlU"
,其中包含有关使用哪个签名密钥等的信息,所以我很确定我的解释是正确的。
它们具有相同的kid
值。 (因为我从 JWKS 端点获取密钥,所以即使它们没有,我也希望它能够工作 - 验证码应该能够为每个令牌选择正确的签名证书。但他们可以,所以那不是问题...)
@KavinduDodanduwa:即使我跳过原始访问令牌的令牌验证,并且仅验证从刷新端点返回的令牌,它仍然会失败并显示相同的消息。
以防万一。我注意到您正在使用 AAD v2 众所周知的 openid-configuration (login.microsoftonline.com/$AZURE_TENANT/v2.0/.well-known/openid-configuration)。不应该使用v1吗? (login.microsoftonline.com/$AZURE_TENANT/.well-known/openid-configuration)
【参考方案1】:
您的代码使用 v1 端点来获取初始访问令牌,但使用 v2 端点来清除刷新令牌。这两个端点的操作方式不同。特别是,v1 端点使用“资源”,而 v2 使用“范围”。
发生这种情况的原因是您显式调用 v1,但依赖于 v2 /openid-configuration
用于刷新令牌端点。
要更正此问题,请将refresh-auth-token.js
的第 19 行更改为
const configResponse =
await fetch(`https://login.microsoftonline.com/$AZURE_TENANT/.well-known/openid-configuration`)
【讨论】:
这是一个很好的线索,但它并没有让我一路走好。尽管刷新的令牌现在通过了验证,但它不适用于https://graph.microsoft.com/v1.0/me
的 Microsoft Graph 查找(它返回正文 error: code: 'InvalidAuthenticationToken', message: 'Access token validation failure.', innerError: 'request-id': '8908cf4d-556e-4ae7-b0d6-7823df85a889', date: '2018-06-25T07:47:11'
)。我认为这可以通过确保在两种情况下都使用v2
端点来解决,但我无法弄清楚初始身份验证请求的正确v2
端点应该是什么。
我写了一个关于 v2 Endpoint 的演练可能会有所帮助:massivescale.com/topic/v2endpoint
谢谢!我也能够重新配置 Passport 以使用 v2 端点来创建初始令牌,但无论如何我都没有设法让它正确验证。但是,我不需要需要使用用户的令牌来访问 Microsoft Graph(我们目前正在使用从堆栈中其他地方获得的 v2 令牌来执行此操作)所以我将其保留为是的,并且现在对 v1 端点感到满意。感谢大家的帮助!以上是关于刷新的 OAuth2 令牌具有无效签名 (Azure AD OAuth2)的主要内容,如果未能解决你的问题,请参考以下文章
使用刷新令牌时 Spring Boot JWT 令牌无效签名
撤销/使 .boto 文件(gsutil config)中生成的 oauth2 刷新令牌无效
尝试使用spring oauth2中的刷新令牌获取新的访问令牌时出现无效的客户端错误
“AADSTS5002730:无效的 JWT 令牌。 Azure Signal R 服务令牌的代表方案中出现“签名算法的密钥不受支持”错误