使用刷新令牌授予类型但保留现有刷新令牌

Posted

技术标签:

【中文标题】使用刷新令牌授予类型但保留现有刷新令牌【英文标题】:Use refresh token grant type but keep existing refresh token 【发布时间】:2021-11-14 09:20:31 【问题描述】:

使用Doorkeeper Ruby gem,我想通过向/oauth/tokens 发送带有正文的POST 来获取新的访问令牌

 grant_type: :refresh_token, refresh_token: 'abc123', scope: :A 

但是,我不希望响应包含替换刷新令牌。即使我明确设置了配置use_refresh_token(false),响应总是包含一个新的刷新令牌。使用grant_type: :refresh_token时有什么方法可以避免生成新的刷新令牌?

我想这样做的原因是,客户端可以请求具有更少范围的 JWT,同时仍保留具有更多范围的现有刷新令牌。

【问题讨论】:

【参考方案1】:

refresh token rotation 行为正在成为标准,因为它是 OAuth 2.1 规范的一部分。

刷新令牌不应该丢失任何范围,并且行为应该是这样的。值得通过几个 curl 请求对 Doorkeeper 进行快速测试:

在用户进行身份验证时,Doorkeeper 将针对委托的范围(用户可能已同意)存储在其数据库中的某个位置。这些可能是范围 A、B 和 C。

然后,客户端选择仅使用范围 B 进行访问令牌刷新。返回一个新的刷新令牌,以及一个范围缩小的访问令牌。

客户端应该仍然能够使用新的刷新令牌再次对范围 A、B 和 C 进行新的刷新,因为委托没有任何改变。

【讨论】:

我在 Doorkeeper 的实现中看到的行为是,在第 2 步中,新的刷新令牌具有比原始刷新令牌更小的范围集(在您的示例中,只有范围 B)。这意味着当我使用新的访问令牌时,我将永久失去对范围 A 和 C 的访问权限。我无法使用旧的刷新令牌(因为它已被撤销)和新的刷新令牌(因为它缺少那些范围)。我错过了什么吗? 我仍然会尝试使用新的刷新令牌来尝试获取具有所有范围的新访问令牌 - 看看这是否有效。只有访问令牌使用范围 - 刷新令牌内容(如果可读)应该无关紧要 - 因为真正的范围应该存储在服务器状态下的委托。

以上是关于使用刷新令牌授予类型但保留现有刷新令牌的主要内容,如果未能解决你的问题,请参考以下文章

带有刷新令牌的 Keycloak 客户端凭据授予类型

Laravel Passport 密码授予刷新令牌

使用 Spring oAuth2 impl,是不是可以在刷新令牌授予期间“降级”访问令牌的范围?

护照密码授予令牌刷新

Spring oauth2刷新令牌 - 无法将访问令牌转换为JSON

refresh_token 是不是应该刷新未过期的访问令牌