我有一个程序,与YouTube直播API集成。它在计时器上运行,所以对我来说,每50分钟用刷新令牌获取一个新的访问令牌相对容易。我的问题是,为什么?
当我通过YouTube认证时,它给了我一个刷新令牌。然后,我大约每小时使用这个刷新令牌来获得一个新的访问令牌。如果我有刷新令牌,我总是可以使用它来获得一个新的访问令牌,因为它永远不会过期。因此,我不认为这比从一开始就给我一个访问令牌而不打扰整个刷新令牌系统更安全。
我有一个程序,与YouTube直播API集成。它在计时器上运行,所以对我来说,每50分钟用刷新令牌获取一个新的访问令牌相对容易。我的问题是,为什么?
当我通过YouTube认证时,它给了我一个刷新令牌。然后,我大约每小时使用这个刷新令牌来获得一个新的访问令牌。如果我有刷新令牌,我总是可以使用它来获得一个新的访问令牌,因为它永远不会过期。因此,我不认为这比从一开始就给我一个访问令牌而不打扰整个刷新令牌系统更安全。
当前回答
refresh_token模式使OAuth服务器处于控制状态,因此当发生不好的事情(如access_token和refresh_token泄露)时,服务器可以进行干预。
e.g.
如果access_token和refresh_token落入黑客手中,access_token将很快过期,黑客可能会尝试刷新令牌,但服务器现在有能力/控制不再发出access_token(考虑到服务器获得了泄漏信息)。
其他回答
使用短时间的访问令牌和长时间的刷新令牌至少有3个相关的原因。
不记名的令牌
从最初的问题:
如果我有刷新令牌,我总是可以使用它来获得一个新的访问令牌,因为它永远不会过期。
虽然您可能总是能够使用刷新令牌获得新的访问令牌,但攻击者通常不能。这是因为你对刷新令牌的使用与你作为客户端的身份证明相结合,例如通过提供你的client_secret。访问令牌不需要这样的证明,因为访问令牌是持名令牌,也就是说,简单地呈现它们就足够了。
如果访问令牌是短期的,则在一定程度上减轻了这种访问令牌的无限功能。
攻击面
访问令牌与(可能有许多)资源服务器交换,这增加了泄漏的机会。刷新令牌只与授权服务器交换。
同样,访问令牌的短寿命至少是某种程度上的缓解。
撤销
将访问令牌实现为有签名的jwt是可能的(也是常见的)。在这种情况下,任何服务器(知道签名方的公钥,通常位于某个众所周知的位置)都可以独立地验证访问令牌的正确性。这可以很好地实现体系结构的解耦,因为资源服务器不必向授权服务器询问授权。
这种设置的缺点是不能撤销这样的令牌(不需要像撤销授权服务器的公钥那样激烈的操作)。
通过使访问令牌的生命周期很短,可以简单地允许它们运行完,而不是显式地撤销。
刷新令牌至少有两个用途。首先,刷新令牌是一种“证明”,证明OAuth2客户端已经从用户那里获得了访问其数据的权限,因此可以再次请求新的访问令牌,而不需要用户经历整个OAuth2流程。其次,与长时间的访问令牌相比,它有助于增加整个安全流。我将更详细地讨论这两点。
刷新令牌作为一种不惹恼用户的方法
Let's talk about the first purpose with an example. Suppose you, a User, were using a third party Client web application that wanted to interact with your YouTube account data. Once you grant permission to the Client application to use your YouTube data, would you want the Client app to prompt you for your permission again when its YouTube token expired? What happens if the YouTube token expiry time was something very low, like 5 minutes. It would get a little annoying having the Client application prompt you for your permission at least every 5 minutes! The solution that OAuth2 proposes to this 'problem' is refresh tokens. By using refresh tokens, the access token can remain short-lived (which is desirable in case the access token is leaked or stolen somehow), and the refresh token can remain long(er)-lived, allowing the Client to get a new access token when one expires without requiring the user's permission (again).
But why a refresh token? If the point is to not bug the User with permission requests, then why can't the Client simply say "Hey, Authorization Server, I want another access token. Now!"? Or, "Hey Authorization Server, here is my expired token, give me a new one!". Well, the refresh token serves as a kind of "proof" that the Client at some original point in time was granted access by a User. This "proof" is in the form of the refresh token being digitally signed by the Authorization Server. By the Client presenting a refresh token, the Authorization Server can verify that the Client received, at some point in the past, permission from the User, and the Client does not have to prompt the User again.
刷新令牌作为提高安全性的一种手段
然而,这就提出了一个问题,“如果刷新令牌被泄露或被盗,或者只是被恶意客户端应用程序保留,而不应用户的请求删除它,会发生什么呢?”攻击者不能继续使用刷新令牌无限期地获得有效的访问令牌(或直到它过期)吗?这个问题导致讨论我提到的第二个目的,即刷新令牌有助于更安全的流程。
The issue that arises with access tokens is that, once acquired, they only ever get presented to the Resource Server (YouTube for example). So if an access token is stolen or compromised, how do you tell the Resource Server not to trust that token? Well, you can't really. The only way to do it would be to change the private signing key on the Authorization Server (the key that signed the token in the first place). I imagine this is inconvenient to do, and in some cases (like Auth0), is not supported.
另一方面,刷新令牌需要频繁地呈现给授权服务器,因此如果其中一个令牌被泄露,那么撤销或拒绝整个刷新令牌是很简单的,而不必更改任何签名密钥。
下面是OAuth 2.0文档中的信息。
刷新令牌用于在当前访问令牌失效或过期时获取新的访问令牌,或获取具有相同或更窄范围的其他访问令牌(访问令牌的生命周期可能比资源所有者授权的权限更短)。
+--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
| |--(C)---- Access Token ---->| | | |
| | | | | |
| |<-(D)- Protected Resource --| Resource | | Authorization |
| Client | | Server | | Server |
| |--(E)---- Access Token ---->| | | |
| | | | | |
| |<-(F)- Invalid Token Error -| | | |
| | +----------+ | |
| | | |
| |--(G)----------- Refresh Token ----------->| |
| | | |
| |<-(H)----------- Access Token -------------| |
+--------+ & Optional Refresh Token +---------------+
(A)客户端通过认证请求访问令牌 授权服务器和呈现授权授予。
(B)授权服务器对客户端进行身份验证和验证 授权授予,如果有效,则发出访问令牌 和一个刷新令牌。
(C)客户端向资源发出受保护资源请求 通过显示访问令牌来访问服务器。
(D)资源服务器验证访问令牌,如果有效, 为请求服务。
(E)步骤(C)和(D)重复直到访问令牌过期。如果 客户端知道访问令牌过期,则跳过步骤(G); 否则,它将发出另一个受保护资源请求。
(F)由于访问令牌无效,资源服务器返回 无效的令牌错误。
(G)客户端通过验证请求一个新的访问令牌 授权服务器和显示刷新令牌。的 客户端身份验证需求取决于客户端类型 以及授权服务器策略。
(H)授权服务器对客户端进行身份验证和验证 刷新令牌,如果有效,发出一个新的访问令牌(并且, 可选的,一个新的刷新令牌)。
“所以我不认为这比从一开始就给我一个访问令牌,而不打扰整个刷新令牌系统更安全。” 我也纠结于同样的问题。简单的回答是,刷新令牌对于确保凭证没有过期是必要的。
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分钟才使用一次来刷新访问令牌(以获得新的访问令牌),而访问令牌则在每次访问资源时使用,这要频繁得多。
因此,您最好同时使用访问令牌和刷新令牌。