OAuth 2.0协议草案的第4.2节指出,授权服务器既可以返回access_token
(用于通过资源对自身进行身份验证),也可以返回(refresh_token
仅用于创建新的)access_token
:
https://tools.ietf.org/html/rfc6749#section-4.2
为什么两者都有?为什么不只要access_token
持续最后一个就refresh_token
没有refresh_token
?
OAuth 2.0协议草案的第4.2节指出,授权服务器既可以返回access_token
(用于通过资源对自身进行身份验证),也可以返回(refresh_token
仅用于创建新的)access_token
:
https://tools.ietf.org/html/rfc6749#section-4.2
为什么两者都有?为什么不只要access_token
持续最后一个就refresh_token
没有refresh_token
?
Answers:
刷新令牌的想法是,如果访问令牌由于生存期短而遭到破坏,则攻击者将有一个滥用它的窗口。
刷新令牌(如果遭到破坏)是无用的,因为攻击者除了需要刷新令牌之外还需要客户端ID和机密才能获得访问令牌。
话虽如此,因为对授权服务器和资源服务器的每次调用都是通过SSL进行的-包括原始客户端ID和请求请求访问/刷新令牌时的机密-我不确定访问令牌的含义如何”而不是长期的刷新令牌和clientid / secret组合。
当然,这与不同时控制授权服务器和资源服务器的实现有所不同。
这是一个讨论刷新令牌使用的好线程:OAuth Archives。
上面的引言,谈到了刷新令牌的安全性目的:
刷新令牌...减轻了access_token长期泄漏的风险(非安全资源服务器,beta或编码不正确的资源服务器应用程序,非https站点上的JS SDK客户端上的日志文件中的查询参数,将access_token放入Cookie等)
由Catchdave提供的讨论链接具有 Dick Hardt提出的另一个有效点 (原始的,无效的链接),除了上面的内容外,我认为在这里值得一提:
我对刷新令牌的回忆是为了安全性和撤消。<...>
撤销:如果访问令牌是自包含的,则可以通过不颁发新的访问令牌来撤消授权。资源无需查询授权服务器即可查看访问令牌是否有效。这简化了访问令牌验证,并使扩展和支持多个授权服务器更加容易。访问令牌有效但授权被撤消存在一段时间。
确实,在Resource Server和Authorization Server是同一实体,并且用户与它们中的任何一个之间(通常)同等安全的情况下,将刷新令牌与访问令牌分开并没有太大意义。
尽管如引用所述,刷新令牌的另一个作用是确保用户可以随时撤消访问令牌(例如,通过其配置文件中的Web界面),同时保持系统可扩展性。 。
通常,令牌可以是指向服务器数据库中特定记录的随机标识符,也可以本身包含所有信息(例如,此信息必须使用MAC进行签名)。
具有长期访问令牌的系统应如何工作
服务器允许客户通过发出令牌来在一组预定义的范围内访问用户的数据。因为我们要使令牌可撤消,所以我们必须将令牌以及已设置或未设置的“已撤销”标志一起存储在数据库中(否则,如何使用自包含令牌?)数据库可以包含与len(users) x len(registered clients) x len(scopes combination)
记录一样多的记录。 。然后,每个API请求都必须访问数据库。尽管对执行O(1)的数据库进行查询非常琐碎,但单点故障本身可能会对系统的可伸缩性和性能产生负面影响。
具有长期刷新令牌和短期访问令牌的系统应如何工作
在这里,我们发出两个密钥:具有数据库中相应记录的随机刷新令牌,以及已签名的自包含访问令牌,其中包含过期时间戳记字段。
由于访问令牌是独立的,因此我们完全不必点击数据库即可检查其有效性。我们要做的就是解码令牌并验证签名和时间戳。
尽管如此,我们仍然必须保留刷新令牌的数据库,但是对该数据库的请求数通常由访问令牌的寿命来定义(寿命越长,访问速率越低)。
为了撤消特定用户对客户端的访问,我们应将相应的刷新令牌标记为“已撤消”(或将其完全删除),并停止发行新的访问令牌。很明显,尽管有一个窗口在其中刷新令牌已被吊销,但是其访问令牌可能仍然有效。
权衡
刷新令牌部分地消除了访问令牌数据库的SPoF(单点故障),但是它们有一些明显的缺点。
窗户”。事件“用户撤消访问权限”和“保证撤消访问权限”之间的时间范围。
客户逻辑的复杂性。
没有刷新令牌
带有刷新令牌
我希望这个答案确实有意义,并且可以帮助别人做出更周到的决定。我还要指出,一些著名的OAuth2提供程序(包括github和foursquare)采用了不带刷新令牌的协议,因此对此感到满意。
尽管有上述所有出色的答案,但作为安全硕士和程序员,我以前曾在eBay工作过,当时我研究了买家保护和欺诈行为,可以说分离访问令牌和刷新令牌在骚扰频繁使用用户名的用户之间具有最佳的平衡。/ password输入并掌握授权,以撤消对您的服务可能造成滥用的访问权限。
考虑这样的情况。您向用户颁发了3600秒的访问令牌,并且刷新令牌的时间长达一天。
该用户是一个好用户,他在家中,就可以在您的iPhone上开/关您的网站购物和搜索。他的IP地址不会改变,并且服务器负载很低。每分钟有3-5页的请求。当他在访问令牌上的3600秒结束时,他需要一个带有刷新令牌的新令牌。在服务器端,我们检查了他的活动历史记录和IP地址,认为他是一个人并且表现得很好。我们授予他新的访问令牌以继续使用我们的服务。在达到刷新令牌本身的一天寿命之前,用户将不需要再次输入用户名/密码。
该用户是粗心的用户。他住在美国纽约,并关闭了病毒程序,并被波兰的一名黑客入侵。当黑客获得访问令牌和刷新令牌时,他会尝试模拟用户并使用我们的服务。但是在短期访问令牌过期后,当黑客尝试刷新访问令牌时,我们在服务器上注意到用户行为历史记录中IP发生了巨大变化(嘿,这个人登录美国,现在在波兰刷新访问权限只需3600秒???)。我们终止刷新过程,使刷新令牌本身无效,并提示再次输入用户名/密码。
该用户是恶意用户。他打算通过使用机器人每分钟调用1000次我们的API来滥用我们的服务。他可以这样做直到3600秒之后,当他尝试刷新访问令牌时,我们注意到他的行为,并认为他可能不是人类。我们拒绝并终止刷新过程,并要求他再次输入用户名/密码。这可能会破坏其机器人的自动流程。至少使他不舒服。
当我们尝试平衡工作,用户体验和令牌被盗的潜在风险时,您可以看到刷新令牌运行良好。您在服务器端的看门狗不仅可以检查IP更改,api调用的频率,还可以确定该用户是否为好用户。
换句话说,您还可以尝试通过在每个api调用上实现基本IP看门狗或任何其他措施来限制对被盗令牌/服务滥用的破坏控制。但这很昂贵,因为您必须读写有关用户的记录,并且会减慢服务器的响应速度。
这些答案都不是刷新令牌存在的核心原因。显然,您始终可以通过将客户端凭据发送到auth服务器来获得新的访问令牌/刷新令牌对-这就是您首先获得它们的方式。
因此,刷新令牌的唯一目的是限制对通过电线发送给auth服务的客户端凭据的使用。访问令牌的ttl越短,则必须使用客户端凭据的次数越多,以获得新的访问令牌,因此,攻击者必须越多地破坏客户端凭据(尽管如果这样做,这可能会非常困难)使用非对称加密来发送它们)。因此,如果您有一次性使用的刷新令牌,则可以在不影响客户端凭据的情况下任意减小访问令牌的ttl。
为了消除混乱,您必须了解客户端机密和用户密码的角色,它们的作用是非常不同的。
该客户端是一个应用程序/网站/程序/ ...,由服务器来说,要支持验证一个用户通过使用第三方认证服务。客户端密钥是此客户端和身份验证服务器都知道的(随机)字符串。客户端可以使用此机密向身份验证服务器标识自己,从而获得请求访问令牌的授权。
要获取初始访问令牌和刷新令牌,需要执行以下操作:
但是,要获取刷新的访问令牌,客户端将使用以下信息:
这清楚地表明了区别:刷新时,客户端通过使用其客户端密码获得授权来刷新访问令牌,因此可以使用刷新令牌(而不是用户ID +密码)重新认证用户。这有效地防止了用户不得不重新输入他/她的密码。
这也表明丢失刷新令牌没有问题,因为客户端ID和密码未知。这也表明,将客户端ID和客户端机密保密至关重要。
答案是来自Justin Richer的OAuth 2标准正文电子邮件列表。这是在他的允许下发布的。
刷新令牌的生命周期由(AS)授权服务器决定,它们可以到期,被吊销,等等。刷新令牌和访问令牌之间的区别在于受众:刷新令牌仅返回授权服务器,访问令牌将转到(RS)资源服务器。
另外,仅获得访问令牌并不意味着用户已登录。实际上,用户可能不再在那里,这实际上是刷新令牌的预期用例。刷新访问令牌将使您能够代表用户访问API,但不会告诉您用户是否在那里。
OpenID Connect不仅为您提供访问令牌中的用户信息,还为您提供了ID令牌。这是一条直接针对客户端本身的数据,而不是AS或RS。在OIDC中,如果您可以获得新的ID令牌,则仅应考虑该协议实际“登录”了某人。刷新它可能还不够。
为什么不让access_token持续到refresh_token那么长而没有refresh_token?
除了其他人提供的好答案之外,还有另一个原因为什么要使用刷新令牌及其与声明有关。
每个令牌都包含声明,这些声明可以包括用户名,他们的角色或创建声明的提供者的任何内容。令牌更新后,这些声明就会更新。
如果我们更频繁地更新令牌,那么显然会给我们的身份服务带来更大的压力,但是我们会获得更加准确和最新的声明。
为了进一步简化BT的回答:当您通常不希望用户再次输入凭据,但仍然希望能够撤消权限(通过撤消刷新令牌)时,请使用刷新令牌。
您不能撤消访问令牌,只能撤消刷新令牌。
这个答案是在两位资深开发人员(约翰·布雷顿和大卫·詹尼斯)的帮助下综合起来的。
使用刷新令牌的主要原因是为了减少攻击面。
让我们假设没有刷新键,让我们来看这个例子:
一幢建筑物有80门。所有门都用同一把钥匙打开。密钥每30分钟更改一次。在30分钟结束时,我必须将旧密钥交给密钥制作者并获得新密钥。
如果我是黑客并获得了您的密钥,那么在30分钟结束时,我将把它快递给密钥制作者并获得一个新密钥。无论钥匙如何更改,我都可以连续打开所有门。
问题:在30分钟内,我有多少次针对密钥的黑客入侵活动?每次您使用密钥时,我都有80次黑客机会(可以将其视为发出网络请求并传递访问令牌以识别自己的身份)。这就是80倍的攻击面。
现在让我们来看一个相同的例子,但是这次我们假设有一个刷新键。
一幢建筑物有80门。所有门都用同一把钥匙打开。密钥每30分钟更改一次。要获得新密钥,我无法传递旧的访问令牌。我只能传递刷新密钥。
如果我是黑客并获得了您的密钥,则可以使用它30分钟,但在30分钟结束时将其发送给密钥制作者没有任何价值。如果我这样做了,那么密钥创建者只会说这个错误的刷新令牌。为了能够扩展我的破解能力,我必须将快递员破解给密钥制作者。快递员有一个独特的钥匙(可以将其视为刷新令牌)。
问题:在30分钟内,我有多少次针对刷新密钥的骇客机会?80?不。我只有1次骇客机会。在此期间,快递员与制琴师进行沟通。这就是1X攻击面。我确实有80次针对密钥的骇客机会,但是30分钟后它们就不好了。
服务器将根据凭据和(通常)JWT的签名来验证访问令牌。
访问令牌泄漏很严重,但是一旦过期,它就不再对攻击者有用。刷新令牌泄漏的情况要严重得多,但是大概不太可能。(我认为还有余地要质疑刷新令牌泄漏的可能性是否比访问令牌泄漏的可能性低得多,但这就是这个主意。)
关键是访问令牌会添加到您提出的每个请求中,而刷新令牌仅在刷新流程中使用,因此MITM看到令牌的机会较小
频率有助于攻击者。令人伤心的流血 -像SSL中的潜在安全漏洞,客户端中的潜在安全漏洞以及服务器中的潜在安全漏洞,都使泄漏成为可能。
此外,如果授权服务器与处理其他客户端请求的应用程序服务器分离,则该应用程序服务器将永远不会看到刷新令牌。它只会看到不会生存很长时间的访问令牌。
隔离专为安全性而设计。
最后但并非最不重要的是,看到这个很棒的答案
刷新令牌不是什么?
通过刷新令牌更新/撤消访问级别的能力是选择使用刷新令牌的副产品,否则,独立的访问令牌可能会被吊销或在过期时修改访问级别,并且用户会获得新的令牌
假设您花了access_token
很长时间,而没有refresh_token
,那么,在一天之内,骇客access_token
就可以得到它,他可以访问所有受保护的资源!
但是,如果您拥有refresh_token
,那么access_token
的生存时间很短,因此黑客很难对其进行黑客入侵,access_token
因为在短时间后它将无效。
Access_token
不仅可以使用refresh_token
,还可以通过client_id
和来检索client_secret
,而黑客没有。
而刷新令牌由授权服务器保留。访问令牌是自包含的,因此资源服务器可以在不存储令牌的情况下对其进行验证,从而节省了验证时检索的工作量。讨论中缺少的另一点是来自rfc6749#page-55
“例如,授权服务器可以采用刷新令牌轮换,其中在每个访问令牌刷新响应中都会发出新的刷新令牌。先前的刷新令牌无效,但由授权服务器保留。如果刷新令牌受到损害,随后被授权服务器使用攻击者和合法客户端都将显示一个无效的刷新令牌,该令牌将向授权服务器通知违规行为。”
我认为使用刷新令牌的全部目的在于,即使攻击者设法以某种方式设法获得刷新令牌,客户端ID和秘密组合。如果随后的每次刷新请求都导致新的访问令牌和刷新令牌,则可以跟踪随后从攻击者获取新的访问令牌的调用。
A Single-Page Application (normally implementing Single-Page Login Flow) should not under any circumstances get a Refresh Token. The reason for that is the sensitivity of this piece of information. You can think of it as user credentials, since a Refresh Token allows a user to remain authenticated essentially forever. Therefore you cannot have this information in a browser, it must be stored securely.
让我们考虑一个系统,其中每个用户都链接到一个或多个角色,而每个角色都链接到一个或多个访问特权。可以缓存此信息以获得更好的API性能。但是,然后,用户和角色配置可能会发生变化(例如,可能会授予新的访问权限,或者可能会撤销当前的访问权限),并且这些更改应反映在缓存中。
为此,我们可以使用访问和刷新令牌。当使用访问令牌调用API时,资源服务器将检查高速缓存中的访问权限。如果有任何新的访问授权,则不会立即反映出来。一旦访问令牌过期(例如30分钟),并且客户端使用刷新令牌生成新的访问令牌,就可以使用数据库中更新的用户访问权限信息来更新缓存。
换句话说,我们可以将昂贵的操作从每个使用访问令牌的API调用转移到使用刷新令牌生成访问令牌的事件。
首先,客户端通过给予授权授权来与授权服务器进行身份验证。
然后,客户端通过提供访问令牌向资源服务器请求受保护的资源。
资源服务器验证访问令牌并提供受保护的资源。
客户端通过授予访问令牌向资源服务器发出受保护的资源请求,资源服务器在该令牌中对其进行验证并为请求提供服务(如果有效)。重复此步骤,直到访问令牌过期。
如果访问令牌过期,则客户端向授权服务器进行身份验证,并通过提供刷新令牌来请求新的访问令牌。如果访问令牌无效,则资源服务器将无效令牌错误响应发送回客户端。
客户端通过授予刷新令牌来向授权服务器进行身份验证。
然后,授权服务器通过对客户端进行身份验证来验证刷新令牌,并颁发新的访问令牌(如果有效)。
access token + refresh token
?