ChatGPT解决这个技术问题 Extra ChatGPT

为什么访问令牌会过期?

我刚刚开始使用 Google API 和 OAuth2。当客户授权我的应用程序时,我会获得一个“刷新令牌”和一个短暂的“访问令牌”。现在每次访问令牌过期时,我都可以将我的刷新令牌发布到 Google,他们会给我一个新的访问令牌。

我的问题是访问令牌过期的目的是什么?为什么不能只有一个持久的访问令牌而不是刷新令牌?

另外,刷新令牌是否过期?

有关 Google OAuth2 工作流程的更多信息,请参阅 Using OAuth 2.0 to Access Google APIs


E
Eran Hammer

这在很大程度上是特定于实现的,但总体思路是允许提供者发布具有长期刷新令牌的短期访问令牌。为什么?

许多提供商支持安全性非常弱的不记名令牌。通过使它们变得短暂并需要刷新,它们限制了攻击者滥用被盗令牌的时间。

大规模部署不想在每次 API 调用时都执行数据库查找,因此他们发布了可以通过解密验证的自编码访问令牌。但是,这也意味着无法撤销这些令牌,因此它们会在短时间内发行,并且必须刷新。

刷新令牌需要客户端身份验证,这使其更强大。与上述访问令牌不同,它通常通过数据库查找来实现。


两个问题:1)在移动应用程序的情况下,客户端身份验证的要求是否使它变得更强大?因为 client_secret 是应用程序源代码的一部分,所以它根本不是秘密。假设访问令牌也仅通过 TLS 共享(并且您的第一个要点不适用)是否有任何额外的安全性? 2)假设所有这些都在我们的场景中成立(只有 TLS,没有自编码的不可撤销令牌),是否可以发布不会过期的访问令牌?
什么是不记名令牌,它与刷新和访问令牌有什么关系?
@Thilo 我认为这个想法是访问令牌不必是可撤销的。正如 Eran 指出的那样,这使得被请求的服务可以决定是否为请求提供服务而无需在某些数据库中查找访问令牌。 AFAICT,这是分离刷新令牌和访问令牌的真正好处。
访问(持有者?)令牌如何短暂?如果我使用过期的不记名令牌发出请求,刷新令牌将返回一个新的不记名令牌。同样,如果我从他们的 cookie 中窃取了某人的令牌,并用该令牌欺骗了我自己的 cookie,我将它发送到服务器,它会刷新并向我发送一个新的。有什么办法阻止它?不要说IP地址甚至MAC,因为那是不合理的。
@Suamere,这已经解释过了。不记名令牌通过不涉及身份验证数据库的加密过程进行验证,从而使它们对于频繁的资源访问更加有效。刷新令牌在涉及检查数据库以确保其仍然有效的过程中得到验证。现在想想gmail是如何工作的。如果有人从意外的地理位置登录您的帐户,您会收到警报。您可以查看当前可能具有有效刷新令牌的所有位置。您可以注销所有位置,使所有其他刷新令牌无效。
A
Alex Spurling

一些场景可能有助于说明访问和刷新令牌的目的以及设计 oauth2(或任何其他身份验证)系统时的工程权衡:

Web 应用场景

在 Web 应用场景中,您有几个选项:

如果您有自己的会话管理,请将 access_token 和 refresh_token 都存储在会话状态服务中的会话状态中。当用户请求需要您访问资源的页面时,请使用 access_token,如果 access_token 已过期,请使用 refresh_token 获取新的。

让我们假设有人设法劫持了您的会话。唯一可能的就是请求您的页面。

如果您没有会话管理,请将 access_token 放入 cookie 并将其用作会话。然后,每当用户从您的 Web 服务器请求页面时,都会发送 access_token。如果需要,您的应用服务器可以刷新 access_token。

比较 1 和 2:

在 1 中,access_token 和 refresh_token 仅在授权服务器(在您的情况下为 google)和您的应用程序服务器之间通过线路传输。这将在安全通道上完成。黑客可以劫持会话,但他们只能与您的网络应用程序交互。在 2 中,黑客可以拿走 access_token 并对用户已授予访问权限的资源形成自己的请求。即使黑客获得了 access_token,他们也只有一个很短的窗口可以访问资源。

无论哪种方式,refresh_token 和 clientid/secret 只有服务器知道,因此无法从 Web 浏览器获得长期访问。

假设您正在实现 oauth2 并在访问令牌上设置了较长的超时时间:

1)短访问令牌和长访问令牌之间没有太大区别,因为它隐藏在应用服务器中。 2)有人可以在浏览器中获取access_token,然后用它来直接访问用户的资源很长时间。

移动场景

在移动设备上,我知道有几个场景:

将 clientid/secret 存储在设备上,并让设备协调获取对用户资源的访问权限。使用后端应用服务器来保存 clientid/secret 并让它进行编排。使用 access_token 作为一种会话密钥,并在客户端和应用服务器之间传递它。

比较 1 和 2

1)一旦您在设备上拥有客户端 ID/秘密,它们就不再是秘密了。任何人都可以反编译,然后开始表现得好像他们是你一样,当然要得到用户的许可。 access_token 和 refresh_token 也在内存中,可以在受感染的设备上访问,这意味着有人可以在用户不提供凭据的情况下充当您的应用程序。在这种情况下,access_token 的长度对可破解性没有影响,因为 refresh_token 与 access_token 位于同一位置。在 2) 中,clientid/secret 和刷新令牌都被泄露。在这里,access_token 的有效期决定了黑客可以在多长时间内访问用户资源,如果他们掌握了它。

到期长度

在这里,这取决于您使用身份验证系统保护的内容,以及您的 access_token 到期应该多长时间。如果它对用户特别有价值,它应该是简短的。价值不高的东西,可以更长。

像谷歌这样的人不会使 refresh_token 过期。有些人喜欢stackflow。关于到期的决定是用户易用性和安全性之间的权衡。刷新令牌的长度与用户返回长度有关,即将刷新设置为用户返回您的应用的频率。如果刷新令牌没有过期,那么它们被撤销的唯一方法就是显式撤销。通常,登录不会撤销。

希望相当长的帖子有用。


关于 MOBILE SCENARIO 是否将客户端 ID 存储在服务器中并不重要。所以其他任何应用程序都可以向您的服务器发送请求,并可以通过您的服务器访问用户资源,所以它是一样的
是的,但是他们只能访问您提供的设施,而不是完全访问底层令牌。即他们可以冒充您的应用程序。通常,令牌可以具有广泛的权限,而您只需要一个子集。如果您需要,在后端持有令牌会提供进一步的限制。
G
Guillaume

除了其他回复:

一旦获得,访问令牌通常与来自客户端的每个请求一起发送到受保护的资源服务器。这会导致访问令牌窃取和重放的风险(当然,假设访问令牌属于“Bearer”类型(如最初的 RFC6750 中所定义))。

这些风险的例子,在现实生活中:

资源服务器通常是分布式应用程序服务器,与授权服务器相比通常具有较低的安全级别(较低的 SSL/TLS 配置、较少的加固等)。另一方面,授权服务器通常被认为是关键的安全基础设施,并且受到更严格的强化。

访问令牌可能会出现在为资源服务器或客户端上的诊断目的而合法收集的 HTTP 跟踪、日志等中。这些跟踪可以在公共或半公共场所(错误跟踪器、服务台等)进行交换。

后端 RS 应用程序可以外包给或多或少值得信赖的第三方。

另一方面,刷新令牌通常仅通过线路传输两次,并且始终在客户端和授权服务器之间传输:一次由客户端获取,一次由客户端在刷新期间使用(有效地“使”先前的刷新“过期”)令牌)。这是一个非常有限的拦截和重播机会。

最后的想法是,Refresh Tokens 提供的保护非常少,如果有的话,可以防止受感染的客户端。


您对此有所提及,但我要强调的是,获取(或相反无意泄露)令牌的更大攻击面是在应用程序日志或恶意添加的资源服务中(今天不是 MITM 攻击)。几乎在通用 API 后端中的任何地方都可以访问所使用的访问令牌(如果它可以访问 HttpRequest 等对象)。系统中只有两个代码路径可以访问刷新令牌 - 一个首先生成它,另一个将它交换为新的访问令牌。这是一个显着的攻击面差异。
C
Claudio Cherubino

它本质上是一种安全措施。如果您的应用程序遭到入侵,攻击者将只能访问短期访问令牌,而无法生成新的访问令牌。

刷新令牌也会过期,但它们的寿命应该比访问令牌长得多。


但是攻击者是否也可以访问刷新令牌?并且可以使用它来创建新的访问令牌吗?
@levi,黑客无法使用刷新令牌来创建新的访问令牌,因为需要客户端 ID 和客户端密码以及刷新令牌才能生成新的访问令牌。
@Spike True,但该应用程序中是否也嵌入了客户端 ID 和密码?
所以它提供了一些防止数据包嗅探的保护,只要拦截只捕获普通数据请求(Chuck 只获取访问令牌)?听起来有点弱;黑帽只需要等待一段时间,直到用户请求新的访问令牌,然后他将获得客户端 ID、秘密和刷新令牌。
这可能只是我在这里受到阻碍,但是如果通过 SSL 发送它并不会增加另一个可能的安全层。我想我假设每个人都知道 SSL 是什么。