OAuth 2.0协议草案的第4.2节指出,授权服务器可以返回access_token(用于通过资源验证自己)和refresh_token,refresh_taken纯粹用于创建新的access_token:

https://www.rfc-editor.org/rfc/rfc6749#section-4.2

为什么两者都有?为什么不让access_token和refresh_token一样长,而不设置refresh_taken?


当前回答

客户可以通过多种方式受到损害。例如,可以克隆手机。访问令牌过期意味着客户端被迫重新向授权服务器进行身份验证。在重新认证期间,授权服务器可以检查其他特征(IOW执行自适应访问管理)。

刷新令牌允许仅客户端进行重新身份验证,其中重新授权会强制与用户进行对话,许多用户表示他们不愿意这样做。

刷新令牌基本上适用于正常网站可能选择在一小时左右后定期重新验证用户的相同位置(例如银行网站)。由于大多数社交网站都不会重新验证网络用户,因此目前它的使用率并不高,那么他们为什么要重新验证客户端呢?

其他回答

刷新令牌和访问令牌只是术语。

这个小小的类比可以帮助巩固使用访问令牌和刷新令牌背后的理论基础:

假设Alice通过邮寄给Bob一张支票,该支票可以在出票后1小时内兑现(假设),否则银行不会兑现。但Alice还在给银行的邮件中附上了一张纸条,要求银行接受并兑现支票,以防支票延迟(在规定范围内)

当Bob收到这张支票时,如果他看到这张支票被篡改(令牌篡改),他将自己丢弃这张支票。如果没有,他可以把它拿到银行兑现。在这里,当银行注意到发行时间超过了1小时的时限,但看到Alice的签名通知,要求银行在规定的延迟范围内兑现。

看到这张纸条后,银行会尝试验证签名的消息,并检查Alice是否仍然具有正确的权限。如果是,银行将支票兑现。鲍勃现在可以向爱丽丝承认这一点了。

虽然不是非常准确,但这个类比可以帮助您注意到处理事务所涉及的不同部分:

Alice(发件人-客户)Bob(接收者-资源服务器)银行(授权服务器)验证过程(数据库访问)支票(访问令牌)备注(刷新令牌)

主要是,为了优化可伸缩性,我们希望减少对Auth Server以及最终对数据库的API调用次数。我们需要在方便和安全之间取得适当的平衡。

注意:与链中的资源服务器相比,让Auth服务器更早地响应请求当然更常见。

这个答案是在两位高级开发人员(约翰·布莱顿和大卫·詹内斯)的帮助下得出的。

使用刷新令牌的主要原因是减少攻击面。

假设没有刷新键,让我们来看看这个示例:

一座大楼有80扇门。所有车门都用同一把钥匙打开。钥匙每30分钟更换一次。在30分钟结束时,我必须把旧钥匙交给钥匙制造商,并获得一把新钥匙。

如果我是黑客,拿到了你的钥匙,那么在30分钟结束后,我会把它快递给钥匙制造商,并获得一把新钥匙。无论换钥匙,我都能连续打开所有车门。

问:在这30分钟里,我有多少次破解钥匙的机会?每次你使用密钥时,我都有80次黑客攻击的机会(把这看作是发出网络请求并传递访问令牌以识别自己)。这是80倍的攻击面。

现在让我们来看看同一个例子,但这次我们假设有一个刷新键。

一座大楼有80扇门。所有车门都用同一把钥匙打开。钥匙每30分钟更换一次。要获取新密钥,我无法传递旧的访问令牌。我只能通过刷新键。

如果我是黑客并得到了你的密钥,我可以使用它30分钟,但在30分钟结束时,将它发送给密钥制作者没有任何价值。如果我这样做了,那么密钥制作者只会说“此令牌已过期。您需要刷新令牌。”为了能够扩展我的黑客攻击,我必须将信使黑客攻击给密钥制作者。信使有一个不同的密钥(将其视为刷新令牌)。

问题:在30分钟内,我有多少次违反刷新键的黑客攻击机会?80? 不,我只有一次黑客攻击机会。在这段时间里,快递员与钥匙制造商进行沟通。这是1X攻击面。我确实有80次破解钥匙的机会,但30分钟后就不行了。


服务器将根据凭证和JWT的签名(通常)验证访问令牌。

访问令牌泄漏是不好的,但一旦过期,它对攻击者不再有用。刷新令牌泄漏的情况要糟糕得多,但估计可能性较小。(我认为,刷新令牌泄漏的可能性是否比访问令牌泄漏的概率低得多,这是一个问题,但这就是想法。)

重点是访问令牌被添加到您发出的每个请求中,而刷新令牌仅在刷新流期间使用所以MITM看到代币的可能性很小

频率有助于攻击者。像SSL中的潜在安全漏洞、客户端中的潜在的安全漏洞以及服务器中潜在的安全缺陷等令人心碎的漏洞都使泄漏成为可能。

此外,如果授权服务器与处理其他客户端请求的应用服务器分离,那么该应用服务器将永远不会看到刷新令牌。它只会看到不会持续很久的访问令牌。

分隔有利于安全。

最后但并非最不重要的刷新令牌可以被旋转。意思是“每次客户端请求将刷新令牌交换为新的访问令牌时,都会返回新的刷新令牌”。随着刷新令牌的不断交换和失效,威胁降低。举个例子:令牌通常在TTL之后过期,通常是一小时。

刷新令牌并不总是,但通常会在使用时被撤销,并发出新的令牌。这意味着,如果您在检索新的刷新令牌时发生网络故障,那么下次发送该刷新令牌时,它将被视为已吊销,您必须登录。

有关旋转的更多信息,请参阅此处和此处

总结

降低频率分区令牌的轮换(更快的失效)和更精细的管理(过期时间或请求数量)。

所有这些都有助于减轻威胁

关于这个问题的另一个观点,请看这个令人敬畏的答案


刷新令牌与什么无关?

通过刷新令牌更新/撤销访问级别的能力是选择使用刷新令牌的一个副产品,否则独立访问令牌可能会被撤销,或在其过期时修改其访问级别,用户将获得新令牌

刷新令牌的思想是,如果访问令牌因其短暂而受到破坏,攻击者可以在有限的窗口中滥用它。

刷新令牌(如果被破坏)是无用的,因为攻击者除了需要刷新令牌之外还需要客户端id和密码,以便获得访问令牌。

话虽如此,由于每次对授权服务器和资源服务器的调用都是通过SSL完成的,包括请求访问/刷新令牌时的原始客户端id和secret,因此我不确定访问令牌如何比长期刷新令牌和客户端id/secret组合更“不可妥协”。

当然,这与不同时控制授权服务器和资源服务器的实现不同。

这里有一个很好的线程,讨论了刷新令牌的使用:OAuth存档。

引用上述内容,讨论刷新令牌的安全目的:

刷新令牌。。。降低长期access_token泄漏的风险(在不安全的资源服务器上的日志文件中查询参数,测试版或编码不良的资源服务器应用程序,非https站点上的JS SDK客户端将access_toke放入cookie等)

这个答案来自Justin Richer通过OAuth 2标准正文电子邮件列表。这是在他的许可下发布的。


刷新令牌的生命周期取决于(AS)授权服务器-它们可以过期、被撤销等。刷新令牌和访问令牌的区别在于受众:刷新令牌只返回授权服务器,访问令牌返回(RS)资源服务器。

此外,仅仅获得访问令牌并不意味着用户已经登录。事实上,用户可能已经不在那里了,这实际上是刷新令牌的预期用例。刷新访问令牌将允许您代表用户访问API,但不会告诉您用户是否在那里。

OpenIDConnect不仅从访问令牌提供用户信息,还提供ID令牌。这是一个单独的数据块,指向客户端本身,而不是AS或RS。在OIDC中,如果您可以获得一个新的ID令牌,您应该只考虑某人实际通过协议“登录”。刷新它可能还不够。

有关更多信息,请阅读http://oauth.net/articles/authentication/

据我所知,如果您需要撤销访问,刷新令牌只是为了性能和成本节省。

例1:不实现刷新令牌;仅实现长期访问令牌:如果用户滥用服务(例如:不支付订阅),您需要能够撤销访问令牌=>您需要在每个需要访问令牌的API调用上检查访问令牌的有效性,这会很慢,因为它需要DB查找(缓存可以帮助,但这更复杂)。

例2:实现刷新令牌和短期访问令牌:如果用户滥用服务(例如:不支付订阅),您需要能够撤销访问令牌=>短暂的访问令牌将在短暂的白色(例如1小时)后过期,用户将需要获得新的访问令牌,因此我们不需要对需要访问令牌的每个API调用进行验证。您只需要在从刷新令牌生成访问令牌时验证用户。对于坏用户,如果无法生成访问令牌,则可以注销该用户。当用户尝试重新登录时,验证将再次运行并返回错误。