为什么访问令牌过期?


209

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

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

另外,刷新令牌会过期吗?

有关Google OAuth2工作流程的更多信息,请参见使用OAuth 2.0访问Google API

Answers:


226

这是非常特定于实现的,但是总的想法是允许提供者发布带有长期刷新令牌的短期访问令牌。为什么?

  • 许多提供程序都支持在安全性方面非常薄弱的​​承载令牌。通过使它们短暂存在并需要刷新,它们限制了攻击者可以滥用被盗令牌的时间。
  • 大规模部署不想在每个API调用时都执行数据库查找,因此,它们会发布可通过解密验证的自编码访问令牌。但是,这也意味着无法撤消这些令牌,因此它们会在短时间内发出并且必须刷新。
  • 刷新令牌需要客户端身份验证,以使其更强大。与上述访问令牌不同,它通常通过数据库查找来实现。

4
两个问题:1)对于移动应用程序,客户端身份验证的要求是否使其变得更强大?因为client_secret是应用程序源代码的一部分,所以它根本不是秘密。假设访问令牌也仅通过TLS共享(并且您的第一个项目符号不适用),是否还有其他安全性?2)假设所有这些情况在我们的方案中都有效(只有TLS,没有自编码的不可撤销令牌),是否可以发行不会过期的访问令牌?
Thilo 2012年

4
什么是承载令牌,它与刷新和访问令牌有什么关系?
allyourcode

7
@Thilo我认为想法是访问令牌不必是可撤销的。正如Eran所指出的,这使所请求的服务可以决定是否为请求提供服务,而不必在某些数据库中查找访问令牌</ em>。AFAICT,这是分离刷新令牌和访问令牌的真正好处。
allyourcode

5
访问(承载)令牌是如何短暂存在的?如果我使用过期的承载令牌发出请求,则刷新令牌将返回一个新的承载令牌。同样,如果我从他们的cookie中窃取某人的令牌,并用该令牌欺骗我自己的cookie,则将其发送到服务器,它将刷新并向我发送一个新的令牌。什么可以阻止呢?不要说IP地址甚至MAC,因为那是不合理的。
Suamere

3
@Suamere,已经解释过了。承载令牌由不接触身份验证数据库的加密过程验证,从而使它们对于频繁的资源访问更加有效。在涉及检查数据库以确保其仍然有效的过程中验证刷新令牌。现在考虑gmail的工作原理。如果有人从意外的地理位置登录到您的帐户,您将收到警报。您可以看到所有可能具有当前有效的刷新令牌的位置。您可以注销所有位置,使所有其他刷新令牌无效。
2015年

33

以下两种情况可能有助于说明访问和刷新令牌的目的以及在设计oauth2(或任何其他auth)系统时的工程设计权衡:

Web应用程序场景

在Web应用程序场景中,您有两个选择:

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

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

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

比较1和2:

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

无论哪种方式,refresh_token和clientid / secret仅对于服务器而言都是已知的,这使得无法从Web浏览器获得长期访问权限。

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

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

移动场景

在移动设备上,我知道一些场景:

  1. 将clientid / secret存储在设备上,并使设备编排获得对用户资源的访问权限。

  2. 使用后端应用服务器来保存clientid / secret,并使其进行编排。使用access_token作为一种会话密钥,并将其在客户端和应用服务器之间传递。

比较1和2

1)一旦在设备上拥有了clientid / secret,它们就不再是秘密了。任何人都可以反编译,然后在得到用户许可的情况下像他们一样开始行动。access_token和refresh_token也位于内存中,并且可以在受到威胁的设备上进行访问,这意味着某人可以充当您的应用程序而无需用户提供其凭据。在这种情况下,access_token的长度对可入侵性没有影响,因为refresh_token与access_token位于同一位置。在2)中,clientid / secret和refresh令牌都被破坏了。在这里,access_token有效期的长度决定了黑客可以在用户掌握资源后访问用户资源的时间。

有效期限

在此,取决于access_token到期时间应长于身份验证系统的安全性。如果它对用户特别有价值,那么它应该简短。有价值的东西可能会更长。

像Google这样的人不会使refresh_token过期。有些像stackflow一样。到期时间的决定是用户使用便利性和安全性之间的权衡。刷新令牌的长度与用户返回的长度有关,即将刷新设置为用户返回应用程序的频率。如果刷新令牌没有过期,则撤销它们的唯一方法是显式撤销。通常,登录不会撤消。

希望篇幅较长的帖子对您​​有所帮助。


关于MOBILE SCENARIO,是否将客户端ID存储在服务器中就无关紧要。因此其他任何应用都可以将请求发送到您的服务器,并可以通过您的服务器访问用户资源,因此保持不变
Amir Bar

是的,但是他们只能访问您提供的功能,而不能完全访问基础令牌。也就是说,他们可以模拟您的应用。通常,令牌可以具有广泛的权限,而您只需要一个子集。如果需要,在后端保留令牌会进一步限制。
艾德·赛克斯

11

除了其他回应:

获取访问令牌后,通常将其与客户端的每个请求一起发送到受保护的资源服务器。这会导致访问令牌被窃取和重放的风险(当然,假设访问令牌的类型为“承载”(如初始RFC6750中所定义)。

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

  • 资源服务器通常是分布式应用程序服务器,并且与授权服务器相比通常具有较低的安全级别(较低的SSL / TLS配置,较少的加固等)。另一方面,授权服务器通常被视为关键的安全基础结构,并且需要经过更严格的加固。

  • 访问令牌可能会显示在HTTP跟踪,日志等中,这些跟踪记录是合法收集的,用于在资源服务器或客户端上进行诊断。这些跟踪可以在公共或半公共场所(错误跟踪器,服务台等)进行交换。

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

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

最后想到的是,Refresh Token对受感染的客户几乎没有提供任何保护。


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

9

这本质上是一种安全措施。如果您的应用受到威胁,则攻击者将只能访问短期访问令牌,而无法生成新令牌。

刷新令牌也将过期,但它们的生存期应比访问令牌长得多。


45
但是攻击者难道也没有访问刷新令牌的权限吗?并且可以使用它来创建一个新的访问令牌吗?
levi

10
@levi,黑客无法使用刷新令牌来创建新的访问令牌,因为需要客户端ID和客户端机密以及刷新令牌才能生成新的访问令牌。
秒杀2012年

9
@Spike True,但应用程序中也没有嵌入客户端ID和密码吗?
安迪

9
因此,只要拦截仅捕获普通数据请求(Chuck仅获取访问令牌),它就可以防止数据包嗅探?听起来有些虚弱。戴黑帽的人只需要稍等片刻,直到用户请求一个新的访问令牌,然后他就可以获取客户端ID,密码和刷新令牌。

3
这可能只是让我受阻,但是如果通过SSL发送,则不会增加另一个可能的安全层。我想我假设每个人都知道SSL是什么。
达蒙·德雷克(
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.