【问题标题】:Refreshed OAuth2 token has invalid signature (Azure AD OAuth2)刷新的 OAuth2 令牌具有无效签名 (Azure AD OAuth2)
【发布时间】:2018-11-27 05:50:24
【问题描述】:

我正在尝试创建一个身份验证流程,其中用户的访问令牌与刷新令牌一起保存在服务器端会话中,当令牌过期时,如果会话仍然有效,它会被更新。但是,在使用与原始令牌相同的方法进行验证时,刷新后我从 Azure AD 返回的令牌具有无效签名。

这是一个说明问题的可运行要点:https://gist.github.com/tlycken/fdaf47dc31e03de43a1a07fbbea2ab91

我所做的基本上是这样的:

  1. 当用户请求页面时,检查会话。如果不存在,则重定向到/auth,该/auth 将重定向到 Azure AD,当我返回时,我有一个有效的令牌存储在会话中。

  2. 使用jwks-rsa 验证会话中的令牌。 (这通常工作正常,所以我特意在令牌字符串中添加一些内容,以使测试代码中的签名无效。)

  3. 如果令牌验证失败,并且会话中有刷新令牌,请尝试使用该刷新令牌获取新令牌。此请求通常返回状态为200 OK 和一组新的访问/刷新令牌。

  4. 使用与验证旧访问令牌相同的代码验证新访问令牌(现在不会弄乱令牌)。 这应该可以,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)

标签: oauth oauth-2.0 azure-active-directory


【解决方案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 端点感到满意。感谢大家的帮助!
猜你喜欢
  • 2014-05-31
  • 2017-04-20
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 2017-12-13
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多