OAuth 2.0协议草案的4.2节指出授权服务器可以返回a access_token
(用于向资源验证自己)以及a refresh_token
,它纯粹用于创建新的access_token
:
https://tools.ietf.org/html/rfc6749#section-4.2
为什么两者都有?为什么不只是做到access_token
最后只要refresh_token
没有refresh_token
?
由Catchdave提供的讨论链接还有另一个 由Dick Hardt提出的有效点 (原始的,死链接),我认为除了上面所写的内容之外,这里还值得提及:
我对刷新令牌的回忆是为了安全和撤销.<...>
撤销:如果访问令牌是自包含的,则可以通过不发布新的访问令牌来撤销授权.资源不需要查询授权服务器以查看访问令牌是否有效.这简化了访问令牌验证,并使得更容易扩展和支持多个授权服务器.访问令牌有效时有一个时间窗口,但授权被撤销.
实际上,在资源服务器和授权服务器是同一个实体的情况下,以及用户和它们中的任何一个之间的连接(通常)同样安全的情况下,将刷新令牌与访问令牌分开是没有多大意义的.
虽然,如引言中所述,刷新令牌的另一个作用是确保用户可以随时撤销访问令牌(例如,通过其配置文件中的Web界面),同时保持系统可扩展性同时.
通常,令牌可以是指向服务器数据库中特定记录的随机标识符,也可以包含所有信息(当然,这些信息必须通过MAC签名,例如).
具有长期访问令牌的系统应该如何工作
服务器允许客户端通过发出令牌来访问预定义范围集内的用户数据.由于我们希望保持令牌可撤销,我们必须在数据库中存储令牌以及设置或取消设置的标志"已撤销"(否则,您将如何使用自包含令牌执行此操作?)数据库可以包含尽可能多的len(users) x len(registered clients) x len(scopes combination)
记录.然后,每个API请求都必须访问数据库.虽然对这样的数据库执行O(1)查询非常简单,但单点故障本身可能会对系统的可伸缩性和性能产生负面影响.
具有长期刷新令牌和短期访问令牌的系统应该如何工作
这里我们发出两个密钥:随机刷新令牌和数据库中的相应记录,以及签名的自包含访问令牌,其中包含到期时间戳字段.
由于访问令牌是自包含的,我们根本不需要访问数据库来检查其有效性.我们所要做的就是解码令牌并验证签名和时间戳.
尽管如此,我们仍然需要保留刷新令牌的数据库,但是对此数据库的请求数通常由访问令牌的生命周期定义(生命周期越长,访问率越低).
为了撤销客户对特定用户的访问,我们应将相应的刷新令牌标记为"已撤销"(或完全删除)并停止发出新的访问令牌.很明显,虽然有一个窗口,在此窗口期间刷新令牌已被撤销,但其访问令牌可能仍然有效.
权衡
刷新令牌部分消除了访问令牌数据库的SPoF(单点故障),但它们有一些明显的缺点.
窗户".事件"用户撤销访问"和"访问保证被撤销"之间的时间范围.
客户逻辑的复杂性.
没有刷新令牌
使用访问令牌发送API请求
如果访问令牌无效,则失败并要求用户重新进行身份验证
使用刷新令牌
使用访问令牌发送API请求
如果访问令牌无效,请尝试使用刷新令牌更新它
如果刷新请求通过,则更新访问令牌并重新发送初始API请求
如果刷新请求失败,请要求用户重新进行身份验证
我希望这个答案确实有意义并帮助某人做出更周到的决定.我还要注意一些着名的OAuth2提供程序,包括github和foursquare,采用没有刷新令牌的协议,并且看起来很满意.
刷新令牌的想法是,如果访问令牌被泄露,因为它是短暂的,攻击者有一个有限的窗口滥用它.
刷新令牌(如果受到攻击)是无用的,因为除了刷新令牌之外,攻击者还需要客户端ID和机密才能获得访问令牌.
话虽如此,因为对授权服务器和资源服务器的每次调用都是通过SSL完成的 - 包括原始客户端ID和秘密,当他们请求访问/刷新令牌时 - 我不确定访问令牌是如何"可妥协的"比长期刷新令牌和clientid/secret组合.
这当然与您不同时控制授权和资源服务器的实现不同.
这是一个讨论刷新令牌使用的好主题:OAuth Archives.
从上面引用,讨论刷新令牌的安全性目的:
刷新令牌...降低长期访问权限泄露的风险(在不安全的资源服务器,测试版或编码不良的资源服务器应用程序上的日志文件中查询参数,非https站点上的JS SDK客户端将access_token放入饼干等)
尽管上面有很多好的答案,我作为一名安全硕士学生和程序员,曾经在eBay工作过,当我看到买家保护和欺诈时,可以说分开访问令牌和刷新令牌在骚扰频繁用户名的用户之间有最佳平衡 /密码输入并保留手中的权限以撤消对潜在滥用服务的访问权限.
想想这样的场景.您发出访问令牌为3600秒的用户,并将令牌更新为一天.
用户是一个很好的用户,他在家里上网/下车你的网站购物和搜索他的iPhone.他的IP地址不会改变,服务器负载也很低.像每分钟3-5页请求.当他在访问令牌上的3600秒结束时,他需要一个带有刷新令牌的新的令牌.我们在服务器端检查他的活动历史和IP地址,认为他是一个人,并且表现得很好.我们授予他一个新的访问令牌以继续使用我们的服务.用户不需要再次输入用户名/密码,直到他达到刷新令牌本身的一天为止.
用户是粗心的用户.他住在美国纽约,他的病毒程序被关闭,并被波兰的一名黑客入侵.当黑客获得访问令牌并刷新令牌时,他会尝试模拟用户并使用我们的服务.但是在短期访问令牌到期后,当黑客试图刷新访问令牌时,我们在服务器上发现了用户行为历史记录中的一个显着的IP更改(嘿,这个人在美国登录,现在刷新访问波兰仅仅3600s后???).我们终止刷新过程,使刷新令牌本身无效并提示再次输入用户名/密码.
用户是恶意用户.他打算通过使用机器人每分钟拨打1000次我们的API来滥用我们的服务.他可以这么做,直到3600秒后,当他试图刷新访问令牌时,我们注意到他的行为,并认为他可能不是一个人.我们拒绝并终止刷新过程并要求他再次输入用户名/密码.这可能会破坏机器人的自动流动.至少让他感到不舒服.
当我们尝试平衡我们的工作,用户体验和被盗令牌的潜在风险时,您可以看到刷新令牌已经完美地发挥了作用.您在服务器端的看门狗可以检查超过IP更改,api调用的频率,以确定用户是否应该是一个好用户.
另一个词是你也可以尝试通过在每个api呼叫上实施基本的IP看门狗或任何其他措施来限制被盗令牌/滥用服务的损害控制.但这很昂贵,因为您必须读取和写入有关用户的记录,并会降低服务器响应速度.
这些答案都没有达到刷新令牌存在的核心原因.显然,您可以通过将您的客户端凭据发送到auth服务器来获得新的访问令牌/刷新令牌对 - 这就是您首先获得它们的方式.
因此,刷新令牌的唯一目的是限制通过线路发送到auth服务的客户端凭证的使用.访问令牌的ttl越短,客户端凭证必须越频繁地用于获取新的访问令牌,因此攻击者必须破坏客户端凭证的机会越多(尽管如果这可能是非常困难的,如果非对称加密用于发送它们).因此,如果您有一次性使用刷新令牌,则可以使访问令牌的ttl任意小,而不会影响客户端凭据.
为了消除一些困惑,您必须了解客户端密钥和用户密码的角色,这些角色非常不同.
该客户端是一个应用程序/网站/程序/ ...,由服务器来说,要支持验证一个用户通过使用第三方认证服务.客户端密钥是此客户端和身份验证服务器都知道的(随机)字符串.使用此秘密,客户端可以向身份验证服务器标识自己,接收授权以请求访问令牌.
要获取初始访问令牌和刷新令牌,需要的是:
用户ID
用户密码
客户端ID
客户的秘密
要获取刷新的访问令牌,客户端使用以下信息:
客户端ID
客户的秘密
刷新令牌
这清楚地表明了不同之处:刷新时,客户端通过使用其客户端密钥接收刷新访问令牌的授权,因此可以使用刷新令牌而不是用户ID +密码重新验证用户.这有效地防止用户必须重新输入他/她的密码.
这也表明丢失刷新令牌没有问题,因为客户端ID和秘密是未知的.它还表明,保持客户端ID和客户端机密是至关重要的.
这个答案来自Justin Richer通过OAuth 2标准正文电子邮件列表.这是在他的许可下发布的.
刷新令牌的生命周期取决于(AS)授权服务器 - 它们可以过期,被撤销等.刷新令牌和访问令牌之间的区别是受众:刷新令牌仅返回授权服务器,访问令牌转到(RS)资源服务器.
此外,仅获取访问令牌并不意味着用户已登录.事实上,用户可能甚至不再在那里,这实际上是刷新令牌的预期用例.刷新访问令牌将允许您代表用户访问API,它不会告诉您用户是否在那里.
OpenID Connect不仅为您提供来自访问令牌的用户信息,还为您提供ID令牌.这是一个单独的数据,针对客户端本身,而不是AS或RS.在OIDC中,如果您可以获得新的ID令牌,则应该只考虑通过协议实际"登录"的人.刷新它可能不够.
欲了解更多信息,请阅读http://oauth.net/articles/authentication/
客户可能在很多方面受到损害.例如,可以克隆手机.访问令牌过期意味着客户端被迫重新向授权服务器进行身份验证.在重新认证期间,授权服务器可以检查其他特征(IOW执行自适应访问管理).
刷新令牌允许客户端仅重新进行身份验证,其中重新授权强制与用户进行对话,许多人已表示他们不愿意这样做.
刷新令牌基本上适合于普通网站可能选择在一小时左右后定期重新验证用户的相同位置(例如银行网站).目前它没有被高度使用,因为大多数社交网站都没有重新验证网络用户,那么他们为什么要重新验证客户端呢?
为了进一步简化BT的答案:当您通常不希望用户再次输入凭据但仍希望能够撤销权限(通过撤消刷新令牌)时,使用刷新令牌
您无法撤消访问令牌,只能撤消刷新令牌.
为什么不将access_token设为last_token,并且没有refresh_token?
除了其他人提供的很好的答案,还有另一个原因,为什么会使用刷新令牌和它与索赔.
每个令牌包含的声明可以包括来自用户名称,角色或创建声明的提供者的任何内容.随着令牌的刷新,这些声明会更新.
如果我们更频繁地刷新令牌,我们显然会对我们的身份服务施加更大的压力,但是我们正在获得更准确和最新的声明.