何时应该实现刷新令牌以及如何保持无状态?

Posted

技术标签:

【中文标题】何时应该实现刷新令牌以及如何保持无状态?【英文标题】:When you should implement a refresh token and how to remain stateless? 【发布时间】:2020-10-31 16:38:25 【问题描述】:

我正在实施一个身份验证系统。 系统当前使用 JWT 运行,并且没有刷新令牌。 为了让用户在合理的时间内保持登录状态,我们决定将令牌的过期时间设置为 12 小时。 我看到建议的过期时间是 15 分钟。

我的第一个问题是,是否每个想要让用户保持登录超过 15 分钟的应用程序都需要实现刷新令牌? 如果是这样,撤销是唯一的原因,还是安全方式(将刷新令牌保存在 httponly cookie 中,将 JWT 保存在内存中,而不是在 cookie 中公开令牌)也是一个原因?

当我寻找刷新令牌的优势时,我主要看到人们在谈论撤销,并将安全方式作为刷新令牌的实现细节,而不是优势。 但据我了解,这也是刷新令牌的优势之一。

我没有找到没有刷新令牌的 JWT 的过期时间标准。我想知道是不是因为从安全角度来看,在大型系统中不实现刷新令牌太危险了。

我的第二个问题是,是否可以通过将身份声明添加到刷新令牌中来实现刷新令牌并保持无状态(这样我就可以在不访问数据库的情况下生成新的 JWT)和放弃撤销?是安全漏洞吗?

在我看到的所有刷新令牌的实现示例中,我从未见过无状态的,因为它们都希望启用撤销。

我的第三个问题是,如果我没有实施撤销令牌的选项,那么从我在问题一中提到的安全优势中期待,是否有理由使用刷新令牌而不是每次系统收到请求时,只需创建一个具有新过期时间的新 JWT?

【问题讨论】:

【参考方案1】:

关于您的问题:

    如果您希望用户保持登录的时间更长,那么实施刷新令牌是一种方法。我在 Stack Overflow 上看到有人每 10 分钟左右根据身份验证令牌进行一次令牌刷新,但我相信这种方法比刷新令牌要麻烦一些。我还可以想象在身份验证服务器上打开一个会话,将会话 ID 放入 cookie 并根据会话刷新 JWT 身份验证令牌。这样做没有错。

    是的。签署令牌后,您也可以将信息放入令牌中以供将来授权。 (不要输入任何敏感信息,因为这是任何人都可以看到的信息)。想想系统应该如何表现,例如用户的访问权限发生变化。用户可以在他注销之前使用他的访问权限运行吗?假设您不小心授予了用户管理员权限。您希望使用下一个 JWT 身份验证令牌撤销它们,不是吗?

    那么,您希望身份验证令牌与刷新令牌一样长吗?注意会立即发生。世界仍将转动,太阳仍将照耀。我们将身份验证和刷新令牌分开,因为我们希望能够更好地处理危机情况。身份验证令牌是您随时随地使用的令牌。如果其中一项服务将令牌泄露给公众,您不希望最终在几分钟内暴露用户的所有数据。如果令牌在几分钟后变得无效,那么即使它们泄漏,攻击者也有一个小的时间窗口来执行攻击。

【讨论】:

【参考方案2】:

只有当您能以不同于访问令牌的方式保护刷新令牌时,才有意义。如果它们在客户端上存储相同,则几乎没有什么好处(有一些与 TLS 漏洞相关,但可能没有那么多支持实现单独的刷新令牌)。

因此,这就是刷新令牌通常存储在仅限 http 的 cookie 中的原因,因此可以防止 XSS。访问令牌也可以最好以这种方式存储,但您将无法将其发送到不同的来源。

撤销是一个不同的问题。您无法撤销真正的无状态令牌,因此如果您需要撤销令牌,则必须实施有状态的解决方案。这可以带有或不带有刷新令牌,从无状态的角度来看,您撤销哪个并不重要。

因此,虽然您应该始终考虑自己的威胁模型(您希望将哪些威胁缓解到何种程度以及如何缓解),但作为基本经验法则,您应该

如果您不需要无状态(大多数应用程序实际上不需要),并且您总是只发送令牌到它的来源(你没有单点登录或类似的,其中从身份提供者或身份验证服务器等获取的令牌用于不同的服务)。 如果您需要单点登录/联合身份,则使用存储较长时间的刷新令牌或存储在 httpOnly cookie 中的会话 ID 来实现由 javascript 存储的短期访问令牌(例如,在 localStorage 中) , 或者如果您有多个服务会使用您的访问令牌。在这种情况下,您仍然可以考虑在没有刷新令牌的情况下使用更长寿的访问令牌,但您将面临令牌被盗的风险,因为攻击者有更多时间实际使用它们。您可以尝试通过撤销来缓解这种情况,但问题是,您可能不会及时注意到,所以我认为这是一种弱缓解。中等复杂度的 Javascript 应用很可能容易受到 XSS 的攻击(无论使用什么框架,但有些更容易受到攻击)。

因此,您希望为访问令牌接受多长时间的到期时间完全取决于您的确切用例和您的风险偏好 - 但做出明智的决定很重要。

【讨论】:

以上是关于何时应该实现刷新令牌以及如何保持无状态?的主要内容,如果未能解决你的问题,请参考以下文章

仅使用 Spring Security 自定义令牌无状态保护 REST 控制器,同时保持常规状态完整 Web 登录正常工作

为啥 JWT 是无状态认证?

有状态与无状态的区别如何影响小部件何时重建?

如果 oauth 是无状态的,谷歌如何销毁 oauth 令牌?

SPA 中的令牌存储和刷新选项

JWT 令牌中的无状态身份验证和权限