刷新的 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)的主要内容,如果未能解决你的问题,请参考以下文章

oauth2.0 尝试使用刷新令牌时请求无效

无法在 PHP 中刷新 OAuth2 令牌,授权无效

使用刷新令牌时 Spring Boot JWT 令牌无效签名

撤销/使 .boto 文件(gsutil config)中生成的 oauth2 刷新令牌无效

尝试使用spring oauth2中的刷新令牌获取新的访问令牌时出现无效的客户端错误

“AADSTS5002730:无效的 JWT 令牌。 Azure Signal R 服务令牌的代表方案中出现“签名算法的密钥不受支持”错误