为什么OAuth v2具有访问权限和刷新令牌?
OAuth 2.0协议草案的第4.2节指出,授权服务器可以返回一个access_token
(用于validation资源)和一个refresh_token
,纯粹用于创build一个新的access_token
:
https://tools.ietf.org/html/rfc6749#section-4.2
为什么都有? 为什么不直接使用refresh_token
创buildaccess_token
,而不是使用refresh_token
呢?
刷新令牌的想法是,如果一个访问令牌被攻破,因为它是短暂的,攻击者有一个有限的窗口滥用它。
刷新令牌(如果受到威胁)是无用的,因为除了刷新令牌外,攻击者还需要客户端ID和密钥才能获得访问令牌。
话虽如此 ,因为每次对授权服务器和资源服务器的调用都是通过SSL完成的 – 包括原始客户端ID和秘密,当他们请求访问/刷新令牌时 – 我不确定访问令牌是如何“妥协“,而不是长期存在的刷新令牌和秘密/秘密组合。
这当然不同于不同时控制授权和资源服务器的实现。
这里有一个很好的讨论刷新令牌的使用: OAuth Archives 。
从上面的引用,谈到刷新令牌的安全目的:
刷新令牌…缓解长期存在的access_token泄漏的风险(在不安全的资源服务器上的日志文件中查询参数,beta或编码不良的资源服务器应用程序,非https站点上的JS SDK客户端,将access_token放入cookies等)
由Catchdave提供的讨论链接还有另外一个迪克·哈特(Dick Hardt)提出的有效论点 ,除了上面所写的东西外,我认为这里值得一提的是:
我记得刷新令牌是为了安全和撤销。 <…>
撤销:如果访问令牌是自包含的,则可以通过不颁发新的访问令牌来撤销授权。 资源不需要查询授权服务器以查看访问令牌是否有效。这简化了访问令牌validation,并且使得更容易扩展和支持多个授权服务器。 访问令牌有效时有一段时间,但是授权被撤销。
事实上,在资源服务器和授权服务器是相同实体的情况下,以及用户和他们中的任何一个之间的连接(通常)同等安全的情况下,保持刷新令牌与访问令牌分离没有多大意义。
虽然如引用部分所述,刷新令牌的另一个作用是确保访问令牌随时可以被用户(例如,通过其configuration文件中的web界面)撤销,同时保持系统可扩展性。
通常,令牌既可以是指向服务器数据库中特定logging的随机标识符,也可以包含所有信息(当然,这些信息必须用MAC来签名)。
具有长期存取令牌的系统应该如何工作
服务器允许客户端通过发布令牌访问预定义范围内的用户数据。 因为我们想保持令牌是可撤销的,所以我们必须在数据库中存储令牌以及设置或取消设置的标志(否则,你将如何使用自包含的令牌来做到这一点?)数据库可以包含尽可能多的len(users) x len(registered clients) x len(scopes combination)
logging。 每个API请求都必须打到数据库。 尽pipe查询这样的数据库执行O(1)是相当简单的,但是单点故障本身可能会对系统的可伸缩性和性能产生负面影响。
具有长寿命刷新令牌和短期访问令牌的系统应该如何工作
在这里,我们发出两个密钥:随机刷新标记与数据库中的相应logging,以及签名的自包含访问标记,其中包含过期时间戳字段。
由于访问令牌是独立的,所以我们根本不需要访问数据库来检查它的有效性。 我们所要做的就是解码令牌并validation签名和时间戳。
尽pipe如此,我们仍然需要保持刷新令牌的数据库,但是对这个数据库的请求数量一般由访问令牌的生命周期来定义(寿命越长,访问率越低)。
为了撤销特定用户对客户端的访问,我们应该将相应的刷新标记标记为“已撤销”(或完全移除)并停止发布新的访问标记。 很显然,刷新令牌已经被撤销,但是它的访问令牌仍然有效。
权衡
刷新令牌部分消除了Access Token数据库的SPoF(单点故障),但是它们有一些明显的缺点。
-
窗户”。 事件之间的时间间隔“用户撤销访问”和“访问保证被撤销”。
-
客户端逻辑的复杂性。
没有刷新令牌
- 用访问令牌发送API请求
- 如果访问令牌无效,则失败并要求用户重新进行身份validation
与刷新令牌
- 用访问令牌发送API请求
- 如果访问令牌无效,请尝试使用刷新令牌进行更新
- 如果刷新请求通过,则更新访问令牌并重新发送初始API请求
- 如果刷新请求失败,请求用户重新进行身份validation
我希望这个答案是有道理的,并帮助有人作出更深思熟虑的决定。 我还想指出,一些着名的OAuth2提供者,包括github和foursquare,都采用没有刷新令牌的协议,看起来很开心。
尽pipe以上所有的重要答案,我作为一个安全硕士学生和程序员谁曾经在eBay上,当我看看买家保护和欺诈,可以说分开访问令牌和刷新令牌之间的频繁用户名的骚扰用户之间的最佳平衡 /密码input并保持权限,以撤销访问可能的滥用您的服务。
想想这样的情景。 你发出一个3600秒的访问令牌的用户,刷新令牌的时间比一天更长。
-
用户是一个很好的用户,他在家里,并通过他的iPhone在网上购物和search。 他的IP地址不会改变,并且在您的服务器上的负载非常低。 每3-5分钟请求一分钟。 当他在访问令牌上的3600秒结束时,他需要一个新的令牌刷新。 我们在服务器端检查他的活动历史和IP地址,认为他是一个人,并performance自己。 我们授予他一个新的访问令牌,以继续使用我们的服务。 用户不需要再次input用户名/密码,直到刷新令牌本身的寿命达到一天。
-
用户是粗心的用户。 他住在美国纽约,病毒程序被closures,被黑客入侵。 当黑客获得访问令牌和刷新令牌时,他试图冒充用户并使用我们的服务。 但是在短期访问令牌到期后,当黑客试图刷新访问令牌时,我们在服务器上已经注意到用户行为历史上IP剧烈变化(嘿,这个家伙login美国,现在在波兰刷新访问在3600s以后)。 我们终止刷新过程,使刷新令牌本身无效,并提示再次input用户名/密码。
-
用户是恶意用户。 他打算通过使用机器人每分钟拨打1000次我们的API滥用我们的服务。 他可以这样做,直到3600秒后,当他试图刷新访问令牌时,我们注意到他的行为,并认为他可能不是一个人。 我们拒绝并终止刷新过程,并要求他再次input用户名/密码。 这可能会破坏他的机器人的自动stream动。 至less让他不舒服。
当我们尝试平衡我们的工作,用户体验以及被盗取令牌的潜在风险时,您可以看到更新令牌已经完美动作。 服务器端的看门狗可以检查IP更改,api调用的频率,以确定用户是否是好用户。
另一个词是你也可以尝试通过在每一个API调用基本的IP看门狗或任何其他措施实施来限制盗取的令牌/滥用服务的损害控制。 但是,这是昂贵的,因为你必须读和写有关用户的logging,并会减慢你的服务器响应。
这些答案都不是刷新标记存在的核心原因。 显然,通过将您的客户端凭证发送给auth服务器,您总是可以获得一个新的访问令牌/刷新令牌对 – 这就是您如何获得它们的原因。
所以刷新令牌的唯一目的是限制使用通过电线发送的客户证书到authentication服务。 访问令牌的ttl越短,客户端证书越需要用来获取新的访问令牌,因此攻击者必须破坏客户端证书的机会越多(尽pipe如果这样做可能会非常困难不对称encryption被用来发送它们)。 因此,如果您有一次性刷新令牌,则可以使访问令牌的ttl任意小,而不会影响客户端凭据。
这个答案来自Justin Richer通过OAuth 2标准正文邮件列表。 这是张贴他的许可。
刷新令牌的生命周期取决于(AS)授权服务器 – 它们可以过期,被撤销等。刷新令牌和访问令牌之间的区别是受众:刷新令牌只返回给授权服务器,访问令牌去(RS)资源服务器。
另外,获取访问令牌并不意味着用户已经login。实际上,用户甚至可能不在那里,这实际上是刷新令牌的预期用例。 刷新访问令牌将使您可以代表用户访问API,但不会告诉您用户是否在那里。
OpenID Connect不仅提供来自访问令牌的用户信息,还为您提供了一个ID令牌。 这是针对客户端本身而不是AS或RS的单独数据。 在OIDC中,如果您可以获得新的ID令牌,则应该只考虑实际由协议“login”的人员。 刷新它不可能是足够的。
欲了解更多信息,请阅读http://oauth.net/articles/authentication/
要清除一些困惑,你必须了解客户端密码和用户密码的angular色,这是非常不同的。
客户端是一个应用程序/网站/程序/ …,由服务器支持,希望通过使用第三方身份validation服务来validation 用户 。 客户端密钥是一个(随机)string,这个客户端和authentication服务器都知道。 使用这个秘密,客户端可以用身份validation服务器识别自己,接收授权来请求访问令牌。
要获得初始访问令牌和刷新令牌,需要的是:
- 用户标识
- 用户密码
- 客户端ID
- 客户的秘密
要获取刷新的访问令牌, 客户端使用以下信息:
- 客户端ID
- 客户的秘密
- 刷新令牌
这清楚地表明了不同之处:刷新时,客户端通过使用其客户端密钥来接收刷新访问令牌的授权,并且因此可以使用刷新令牌而不是用户ID +密码来重新authentication用户。 这有效地防止用户不得不重新input他/她的密码。
这也表明,丢失刷新令牌是没有问题的,因为客户端ID和秘密是未知的。 这也表明保持客户端ID和客户端的秘密至关重要 。
客户可以通过多种方式妥协。 例如,手机可以被克隆。 访问令牌过期意味着客户端被强制重新authentication到授权服务器。 在重authentication过程中,授权服务器可以检查其他特征(IOW执行自适应访问pipe理)。
刷新令牌允许客户端只重新validation,在那里重新授权强制与许多人表示他们不想做的用户进行对话。
刷新令牌基本上位于正常网站可能select的地点,以便在一个小时左右(例如银行站点)周期性地重新authentication用户。 由于大多数社交网站不重新authenticationnetworking用户,所以目前使用率并不高,为什么要重新authentication客户呢?
为了进一步简化英国电信的答案:当你通常不希望用户必须再次input证书时,使用刷新令牌,但仍然希望权力能够撤销权限(通过撤销刷新令牌)
您不能撤销访问令牌,只能刷新令牌。
为什么不直接使用refresh_token来创buildaccess_token,而不是使用refresh_token呢?
除了其他人提供的很好的答案之外,还有另外一个原因是为什么要使用刷新标记及其与索赔的关系。
每个标记都包含声明,其中可以包含来自用户名称,其angular色或创build声明的提供者的任何内容。 当令牌刷新时,这些索赔被更新。
如果我们更频繁地刷新令牌,显然会给我们的身份服务带来更大的压力,但是我们正在获得更准确和最新的要求。
首先,客户端通过授权授权与授权服务器进行authentication。
然后,客户端通过给予访问令牌向资源服务器请求受保护的资源。
资源服务器validation访问令牌并提供受保护的资源。
客户端通过授予访问令牌向资源服务器发出受保护的资源请求,如果资源服务器validation并访问该请求,则访问令牌服务于该请求(如果有效)。 此步骤不断重复,直到访问令牌到期。
如果访问令牌到期,则客户端通过授权服务器进行authentication,并通过提供刷新令牌来请求新的访问令牌。 如果访问令牌无效,则资源服务器将无效令牌错误响应发送回客户端。
客户端通过授予刷新令牌来向授权服务器进行身份validation。
然后,授权服务器通过validation客户端来validation刷新令牌,并且如果该令牌有效则发出新的访问令牌。
让我们考虑一个系统,每个用户链接到一个或多个angular色,每个angular色链接到一个或多个访问权限。 这些信息可以被caching以获得更好的API性能。 但是,用户和angular色configuration可能会发生变化(例如,可能会授予新的访问权限,或者可能会撤销当前的访问权限),这些都应该反映在caching中。
我们可以使用访问和刷新令牌来达到这个目的。 当使用访问令牌调用API时,资源服务器将检查caching的访问权限。 如果有任何新的准入津贴,它不会立即反映出来。 一旦访问令牌过期(例如在30分钟内)并且客户端使用刷新令牌来生成新的访问令牌,可以使用来自DB的更新的用户访问权限信息来更新caching。
换句话说,我们可以将使用访问令牌的每个API调用的昂贵操作移动到使用刷新令牌生成访问令牌的事件。