我有一个程序,与YouTube直播API集成。它在计时器上运行,所以对我来说,每50分钟用刷新令牌获取一个新的访问令牌相对容易。我的问题是,为什么?
当我通过YouTube认证时,它给了我一个刷新令牌。然后,我大约每小时使用这个刷新令牌来获得一个新的访问令牌。如果我有刷新令牌,我总是可以使用它来获得一个新的访问令牌,因为它永远不会过期。因此,我不认为这比从一开始就给我一个访问令牌而不打扰整个刷新令牌系统更安全。
我有一个程序,与YouTube直播API集成。它在计时器上运行,所以对我来说,每50分钟用刷新令牌获取一个新的访问令牌相对容易。我的问题是,为什么?
当我通过YouTube认证时,它给了我一个刷新令牌。然后,我大约每小时使用这个刷新令牌来获得一个新的访问令牌。如果我有刷新令牌,我总是可以使用它来获得一个新的访问令牌,因为它永远不会过期。因此,我不认为这比从一开始就给我一个访问令牌而不打扰整个刷新令牌系统更安全。
当前回答
使用短时间的访问令牌和长时间的刷新令牌至少有3个相关的原因。
不记名的令牌
从最初的问题:
如果我有刷新令牌,我总是可以使用它来获得一个新的访问令牌,因为它永远不会过期。
虽然您可能总是能够使用刷新令牌获得新的访问令牌,但攻击者通常不能。这是因为你对刷新令牌的使用与你作为客户端的身份证明相结合,例如通过提供你的client_secret。访问令牌不需要这样的证明,因为访问令牌是持名令牌,也就是说,简单地呈现它们就足够了。
如果访问令牌是短期的,则在一定程度上减轻了这种访问令牌的无限功能。
攻击面
访问令牌与(可能有许多)资源服务器交换,这增加了泄漏的机会。刷新令牌只与授权服务器交换。
同样,访问令牌的短寿命至少是某种程度上的缓解。
撤销
将访问令牌实现为有签名的jwt是可能的(也是常见的)。在这种情况下,任何服务器(知道签名方的公钥,通常位于某个众所周知的位置)都可以独立地验证访问令牌的正确性。这可以很好地实现体系结构的解耦,因为资源服务器不必向授权服务器询问授权。
这种设置的缺点是不能撤销这样的令牌(不需要像撤销授权服务器的公钥那样激烈的操作)。
通过使访问令牌的生命周期很短,可以简单地允许它们运行完,而不是显式地撤销。
其他回答
这是一次很好的学习经历,了解了令牌、刷新令牌和缓存它。然而,(我很好奇,我在这里不给出任何建议)我们可以使用用户登录后返回的代码,当使用微软身份平台时。我们是否可以只存储CodeIdToken,并在需要时使用它来获取新的访问令牌?因为我在想,我们用它来获得访问令牌,那么我们应该每次都用来重新生成访问令牌吗?
...
ResponseType = OpenIdConnectResponseType.CodeIdToken,
...
and
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
{
IConfidentialClientApplication clientApp = MsalAppBuilder.BuildConfidentialClientApplication();
AuthenticationResult result = await clientApp.AcquireTokenByAuthorizationCode(new[] { "User.Read" }, context.Code)
.ExecuteAsync();
}
访问令牌生命周期短。一旦它过期,您需要一个新的访问令牌来访问受保护的资源。一种获取新访问令牌的方法是再次验证资源所有者并获得授权,然后获取访问令牌。然而,这很烦人。
这个问题可以用刷新令牌来解决。它的寿命很长。因此,您可以使用它来获得新的访问令牌,而无需与资源所有者交互。
好吧,你可能会想,用长寿命的代币来获得另一个短寿命的钥匙有什么意义呢?好吧,即使刷新令牌被破坏,攻击者也不能从中获取访问令牌。原因是攻击者需要客户端凭据以及刷新令牌。
因此,访问令牌的生命周期将很短(原因可以在其他答案中找到),以提高安全性。为了避免资源所有者在访问令牌过期时感到厌烦,OAuth使用刷新令牌。
access_token使用得更频繁,撤消的能力不是很重要,因为它们的生命周期很短。
refresh_token使用的频率较低,撤消的能力至关重要,因为它们可以用来生成新的access_token。
验证已签名令牌的成本较低,但撤销令牌很困难。
验证存储在数据库中的令牌的成本很高,但很容易撤销。
因此,签名密钥可以用作access_token来提高性能。
Db存储的键可以作为refresh_token使用,以便于撤销它们。
如果没有refresh_token,就很难找到一种提供低成本验证和简单撤销能力的机制。因此refresh_token的存在是由于性能原因。
“所以我不认为这比从一开始就给我一个访问令牌,而不打扰整个刷新令牌系统更安全。” 我也纠结于同样的问题。简单的回答是,刷新令牌对于确保凭证没有过期是必要的。
An example may help: I have a database that stores your medical records. You consent to sharing your medical records with your spouse. Your spouse uses their Access Token to read your records from my database. Two weeks from now your spouse checks again on your medical records and the refresh token is used to ensure they still have permission (from the authentication server) to view your records. The refresh token bypasses the need for your spouse to re-enter their credentials (username and password) to the authentication server, but it does ensure they still have legitimacy to access the resource. A never expiring Access Token would not know if you had revoked your spouse's rights to access your medical records.
只使用访问令牌比同时使用访问令牌和刷新令牌风险大得多。
例如,您只使用访问令牌设置“100天”有效期,但一天,访问令牌被黑客窃取。现在,黑客有很大的机会自由使用访问令牌100天,作为一个坏的目的。
现在,您使用访问令牌集“60分钟”到期日期和刷新令牌集“100天”到期日期,但有一天,访问令牌被黑客窃取。现在,黑客自由使用访问令牌的机会要小得多,最多只能使用60分钟。
现在,您会认为刷新令牌是否被盗。实际上,如果刷新令牌被黑客窃取,黑客仍然有很大的机会免费使用刷新令牌,最多100天用于不良目的。但是,刷新令牌被盗的概率远低于访问令牌被盗的概率,因为刷新令牌每60分钟才使用一次来刷新访问令牌(以获得新的访问令牌),而访问令牌则在每次访问资源时使用,这要频繁得多。
因此,您最好同时使用访问令牌和刷新令牌。