OAuth 2.0协议草案的第4.2节指出,授权服务器可以返回一个access_token
(用于认证资源),以及一个refresh_token
,后者仅用于创建新的access_token
:
https://www.rfc-editor.org/rfc/rfc6749#section-4.2
为什么需要两个令牌?为什么不让access_token
的有效期与refresh_token
相同,而不提供refresh_token
呢?
OAuth 2.0协议草案的第4.2节指出,授权服务器可以返回一个access_token
(用于认证资源),以及一个refresh_token
,后者仅用于创建新的access_token
:
https://www.rfc-editor.org/rfc/rfc6749#section-4.2
为什么需要两个令牌?为什么不让access_token
的有效期与refresh_token
相同,而不提供refresh_token
呢?
正如引文中提到的,刷新令牌的另一个作用是确保用户可以随时撤销访问令牌(例如通过其个人资料中的 Web 界面),同时保持系统的可扩展性。
通常,令牌可以是指向服务器数据库中特定记录的随机标识符,也可以包含所有信息(当然,这些信息必须进行签名,例如使用 MAC)。
长期访问令牌的系统应如何工作
服务器通过发放令牌允许客户端在预定义的一组范围内访问用户数据。由于我们希望保持令牌可撤销,因此我们必须将令牌与设置或取消“已撤销”标志的数据库一起存储(否则,如何处理自包含的令牌?)。数据库可以包含多达 len(users) x len(registered clients) x len(scopes combination)
条记录。然后,每个 API 请求都必须命中数据库。尽管对这样的数据库执行 O(1) 查询相当简单,但单点故障本身可能会对系统的可扩展性和性能产生负面影响。
这位用户是一个恶意用户。他想要利用机器人每分钟调用我们的API 1000次来滥用我们的服务。他可能会一直这样做,直到3600秒后他尝试刷新访问令牌时,我们注意到了他的行为并认为他可能不是人类。我们拒绝和中止刷新过程,并要求他重新输入用户名/密码。这可能会潜在地破坏他的机器人的自动流程, 至少会使他感到不舒服。
您可以看到,在我们尝试平衡工作、用户体验和被盗令牌的潜在风险时,刷新令牌表现得非常出色。您在服务器端的看门狗可以通过检查更多的IP更改、API调用频率等来确定用户是否是好用户。
另外,您也可以通过在每个API调用上实施基本的IP监控或其他措施来尝试限制被盗令牌/滥用服务的损害控制。但这是昂贵的,因为您必须读写有关用户的记录,并会减慢您的服务器响应速度。
这两个答案都没有涉及刷新令牌存在的核心原因。显然,您可以通过向认证服务器发送客户端凭据来获取新的访问令牌/刷新令牌对 - 这就是您首次获取它们的方式。
因此,刷新令牌的唯一目的是限制将客户端凭据发送到身份验证服务的使用。访问令牌的TTL(生存时间)越短,客户端凭据需要用于获取新的访问令牌的次数就越多,因此攻击者就有更多机会来破坏客户端凭据(尽管如果使用非对称加密将它们发送出去,这可能会非常困难)。因此,如果您拥有一个单次使用的刷新令牌,则可以使访问令牌的TTL任意小,而不会危及客户端凭据。
这篇答案是由两位资深开发人员(约翰·布雷顿和大卫·詹纳斯)共同完成的。
使用刷新令牌的主要原因是减少攻击面。
假设没有刷新密钥,让我们通过以下示例进行说明:
一栋建筑有80个门。所有的门都用同一把钥匙打开。钥匙每30分钟更换一次。在30分钟结束时,我必须将旧钥匙交给钥匠并获得新钥匙。
如果我是黑客并得到了你的钥匙,那么在30分钟结束时,我会将其送到钥匠那里并获取一个新钥匙。我将能够持续打开所有门,而不管钥匙是否更改。
问题: 在30分钟内,我有多少次攻击机会?我有80次攻击机会,每次你使用钥匙(将访问令牌传递以识别自己)时都会增加一次。所以攻击面为80X。
现在让我们通过相同的示例来看一下,但这次假设有一个刷新密钥。
一栋建筑有80个门。所有的门都用同一把钥匙打开。钥匙每30分钟更换一次。要获得新钥匙,我不能传递旧的访问令牌。我必须只传递刷新密钥。
如果我是黑客并且拥有你的密钥,我可以在30分钟内使用它,但在30分钟结束后将其发送给钥匠没有任何价值。如果我这么做了,那么钥匠会说“此令牌已过期。您需要刷新令牌。”要延长我的黑客攻击,我必须黑进快递员到钥匠。快递员有一个独特的密钥(将其视为刷新令牌)。频率会帮助攻击者。SSL中类似于Heartbleed潜在的安全漏洞、客户端中潜在的安全漏洞以及服务器中潜在的安全漏洞都可能导致信息泄露。
此外,如果授权服务器与处理其他客户端请求的应用服务器分开,则该应用服务器永远不会看到刷新令牌。它只会看到很快就会过期的访问令牌。
隔离有助于保障安全。
最后,刷新令牌可以被轮换。这意味着“每次客户端请求用于获取新访问令牌的刷新令牌时,都会返回一个新的刷新令牌”。由于刷新令牌不断交换和失效,威胁得到了降低。举个例子:令牌通常在TTL(生存时间)之后失效,通常为一小时。
刷新令牌并不总是在使用后撤销并发出新的。这意味着,如果您遇到网络故障,在检索新的刷新令牌时,下一次发送该刷新令牌时,它将被视为已撤销,您需要重新登录。
所有这些都有助于减轻威胁
另外,可以查看这篇优秀的回答
刷新令牌不是关于什么?
通过刷新令牌更新/撤销访问级别是使用刷新令牌的副产品,否则,在到期并取得新令牌时,可以撤销单独的访问令牌或修改其访问级别
这篇回答来自Justin Richer通过OAuth 2标准邮件列表。已获得他的许可发布。
刷新令牌的生命周期取决于授权服务器(AS)-它们可以过期、被撤销等。刷新令牌和访问令牌之间的区别在于受众:刷新令牌只返回到授权服务器,而访问令牌则返回到资源服务器(RS)。
此外,仅仅获取访问令牌并不意味着用户已登录。实际上,用户可能已经退出了登录,这实际上是刷新令牌的预期用例。刷新访问令牌将让您以用户的名义访问API,但它不会告诉您用户是否仍然在线。
OpenID Connect不仅从访问令牌中提供用户信息,还为您提供了一个ID令牌。这是一个针对客户端本身而不是AS或RS的单独数据。在OIDC中,只有在您可以获得新的ID令牌时才应该考虑某人实际上“已登录”协议。仅仅刷新它很可能不够。
客户端可以通过多种方式被攻击,例如手机可以被克隆。访问令牌过期意味着客户端必须重新向授权服务器进行身份验证。在重新身份验证期间,授权服务器可以检查其他特征(即执行自适应访问管理)。
刷新令牌允许客户端仅进行重新身份验证,而重新授权则强制要求与用户对话,许多人表示他们不愿意这样做。
刷新令牌基本上与普通网站可能会选择每隔一小时左右定期重新验证用��(例如银行网站)的位置相同。目前它并没有得到广泛使用,因为大多数社交网站不会重新验证Web用户,那么他们为什么会重新验证客户端呢?
更简单地说,当你不想让用户再次输入凭据,但仍然希望有能力撤销权限(通过撤销刷新令牌)时,请使用刷新令牌。
你无法撤销访问令牌,只能撤销刷新令牌。