谷歌OAuth令牌验证是如何进行的?为什么要进行验证?

24
在访问令牌、刷新令牌、范围、受众和客户端 ID 之间,当 Google OAuth 文档指示我验证所有令牌以防止混淆的代理问题时,我感到很困惑。链接到维基百科文章仅概述了一般问题,不涉及OAuth甚至网络身份验证。如果我理解正确,令牌验证甚至不是OAuth2的一部分,而实际上取决于具体实现。因此,我的问题是:

Google OAuth如何以及为什么进行令牌验证?

特别欢迎提供在此情况下混淆的代理问题的具体示例。请注意,我是在完全客户端应用程序的情况下提出这个问题的,如果这有所不同。

2个回答

48

谷歌在此特指“访问”令牌。

在OAuth 2.0的背景下,混淆代理问题适用于Implicit Grant协议流在身份验证方面使用时。谷歌所说的“面向客户端应用程序的OAuth 2.0”是基于隐式授权协议流程的。

由于隐式流程通过URI片段将访问令牌暴露给最终用户,因此可能存在访问令牌可能被篡改的可能性。合法的应用程序(OAuth客户端)可以成为混淆代理,通过接受发放给不同(恶意)应用程序的访问令牌,从而使攻击者可以访问受害者的帐户。

验证访问令牌的关键步骤是应用程序验证访问令牌最初没有发放给其他应用程序。谷歌在提到这一点时进行了强调

注意:在验证令牌时,务必确保响应中的受众字段与您在API控制台注册的client_id完全匹配。这是解决“困惑的代理”问题的方法,执行此步骤绝对至关重要。
作为一个简单的例子,假设有两个应用程序:(1)FileStore,一个合法的文件存储应用程序,和(2)EvilApp。这两个应用程序都使用谷歌的客户端应用程序身份验证过程。艾丽斯是一个无辜的最终用户,她的Google用户ID是XYZ。
以下是翻译的结果,按要求保留HTML标签:
  1. Alice使用Google登录FileStore。
  2. 身份验证过程后,FileStore为Alice创建了一个帐户,并将其与Google用户ID XYZ关联。
  3. Alice将一些文件上传到她的FileStore帐户中。目前一切正常。
  4. 稍后,Alice登录EvilApp,该应用程序提供看起来很有趣的游戏。
  5. 因此,EvilApp获得了与Google用户ID XYZ相关联的访问令牌。
  6. EvilApp的所有者现在可以为FileStore构建重定向URI,插入分配给Alice Google帐户的访问令牌。
  7. 攻击者连接到FileStore,它将获取访问令牌并检查Google以查看它属于哪个用户。Google将说它属于用户XYZ。
  8. FileStore会授予攻击者访问Alice的文件的权限,因为攻击者拥有Google用户XYZ的访问令牌。

FileStore的错误在于未验证Google所颁发的访问令牌是否确实是针对FileStore而颁发的;事实上,该令牌实际上是针对EvilApp颁发的。

其他人已经比我更优雅地描述了这个问题:

我希望这段内容能够解释客户端应用程序访问令牌验证中的“为什么”部分,并阐明它与混淆代理问题的关系。请注意,需要保留HTML标签。

2
我认为这很有道理。我的理解是:Google服务器可以确定令牌发给了哪个用户,所以这部分没问题。然而,客户端(没有令牌验证)无法确定令牌发给了哪个客户端。换句话说,是客户端感到困惑。这正确吗? - Jakob
1
用非常简单的语言解释。谢谢。希望每个人都能提供这样的例子! - arajashe
1
@samthebest 我猜测你提到的 id_token 实际上是一个OpenID Connect id_token。你可以从中提取有关用户的信息。http://openid.net/specs/openid-connect-core-1_0.html#TokenResponse - Andre D
1
在我看来,恶意客户端可以通过使用另一个应用程序的客户端ID(客户端ID不是机密)来获取令牌。 - The Tahaan
1
@TheTahaan,你和Andre D在聊天中解决了这个问题吗?我非常关心结论,因为我(像你一样)认为恶意应用程序可以轻易地伪造客户端ID。我不明白重定向URI如何在本机移动应用程序(而不是Web应用程序)的情况下有所帮助 - Facebook不会直接通过重定向URI将访问令牌发送到“好”应用程序,对吧?相反,据我所知,恶意应用程序将收到重定向请求以及访问令牌。 - YSK
显示剩余9条评论

3
你是如何使用OAuth2的?你是获取授权码并交换刷新令牌吗?还是直接通过前端获取访问令牌?
如果你收到了授权码,那么你就完成了,因为Google在后端执行的client_secret检查保证了所有为你的应用程序发放的授权码所返回的令牌。
如果你通过前端收到了access_token+id_token,则应使用推荐的库验证id_token签名,然后验证id_token中的'aud'字段是否与你在Google注册的应用程序匹配。为了完全安全,还需要交叉验证access_token和id_token(id_token包括access_token的截断哈希作为字段“at_hash”),如文档所述:https://developers.google.com/accounts/docs/OAuth2Login

1
你能否在这个背景下解释一下混淆代理问题?那是最令人困惑的部分。 - Jakob
1
混淆代理的含义是你需要检查该令牌是否被颁发给了你的应用程序,而不仅仅是被颁发给了用户。否则,如果您的用户授权另一个应用程序(恶意应用程序),那么恶意应用程序获得的令牌可以用于“认证”用户访问您的应用程序。 - breno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接