如何撤销JWT令牌?

问题描述 投票:50回答:5

我正在使用Spring Security OAuth2和JWT令牌。我的问题是:我如何撤销JWT令牌?

正如这里提到的http://projects.spring.io/spring-security-oauth/docs/oauth2.html,撤销是通过刷新令牌完成的。但它似乎没有用。

oauth-2.0 spring-security-oauth2
5个回答
66
投票

一般来说,最简单的答案就是说你不能撤销JWT令牌,但事实并非如此。诚实的答案是,支持JWT撤销的成本足够大,不值得大部分时间,或者明显重新考虑替代JWT。

话虽如此,在某些情况下,您可能需要JWT和立即令牌撤销,所以让我们看看它会采取什么,但首先我们将介绍一些概念。

JWT(Learn JSON Web Tokens)只是指定一种令牌格式,这种撤销问题也适用于通常称为自包含或按值令牌的任何格式。我喜欢后一种术语,因为它与副参考标记形成了鲜明的对比。

按值令牌 - 相关信息(包括令牌生存期)包含在令牌本身中,并且可以将信息验证为源自可信来源(救援的数字签名)

引用令牌 - 相关信息保存在服务器端存储上,然后使用令牌值作为密钥获取;作为服务器端存储,相关信息是隐式信任的

在JWT Big Bang之前,我们已经在我们的身份验证系统中处理了令牌;应用程序在用户登录时创建会话标识符通常会被使用,这样用户就不必每次都重复登录过程。这些会话标识符被用作服务器端存储的关键索引,如果这听起来类似于您最近阅读的内容,那么您确实将其归类为引用标记。

使用相同的类比,理解副参考令牌的撤销是微不足道的;我们只是删除映射到该密钥的服务器端存储,下次提供密钥时它将无效。

对于按值标记,我们只需要执行相反的操作。当您请求撤销令牌时,您存储了一些允许您唯一标识该令牌的内容,以便下次收到该令牌时,您还可以检查它是否已被撤销。如果您已经在考虑这样的事情无法扩展,请记住,您只需要存储数据,直到令牌到期为止,在大多数情况下,您可能只是存储令牌的哈希值,因此它总是存在是一个已知的大小。

作为最后一点,并以OAuth 2.0为中心,撤销按值访问令牌目前尚未标准化。尽管如此,OAuth 2.0令牌撤销明确指出,只要授权服务器和资源服务器都同意自定义处理方式,它仍然可以实现:

在前一种情况(自包含令牌)中,当需要立即访问令牌撤销时,可以使用授权服务器和资源服务器之间的一些(当前非标准化的)后端交互。

如果您同时控制授权服务器和资源服务器,则很容易实现。另一方面,如果您将授权服务器角色委派给像Auth0这样的云提供商或者像Spring OAuth 2.0这样的第三方组件,那么您很可能需要采用不同的方法,因为您可能只会获得已经标准化的内容。

一个有趣的参考

本文解释了另一种方法:Blacklist JWT它包含一些有趣的实践和模式,其次是RFC7523


15
投票

这是一个名为JWT old的解决方案,用于新的交换模式。

因为我们不能在到期时间之前使发布的令牌无效,所以我们总是使用短时令牌,例如30分钟。当令牌过期时,我们使用旧令牌交换新令牌。关键点是一个旧令牌只能交换一个新令牌。

在中心auth服务器中,我们维护一个这样的表:

table auth_tokens(
    user_id,
    jwt_hash,
    expire
)

user_id包含在JWT字符串中。 jwt_hash是整个JWT字符串的哈希值,例如SHA256。 expire字段是可选的。

以下是工作流程:

  1. 用户使用用户名和密码请求登录API,auth服务器发出一个令牌,并注册令牌(在表中添加一行)。
  2. 当令牌过期时,用户使用旧令牌请求交换API。首先,auth服务器将旧标记验证为正常,除了过期检查,然后创建标记哈希值,然后按用户标识在表上方查找: 如果找到记录,并且user_id和jwt_hash匹配,则发出新令牌并更新表。 如果找到记录,但user_id和jwt_hash不匹配,则表示某人之前已使用令牌交换的新令牌。令牌被黑客攻击,通过user_id删除记录并使用警报信息进行响应。 如果没有找到记录,用户需要再次登录或只输入密码。
  3. 当使用更改密码或登出时,按用户ID删除记录。

要连续使用令牌,合法用户和黑客都需要连续交换新令牌,但只有一个可以成功,当一个失败时,都需要在下次交换时再次登录。

因此,如果黑客获得令牌,它可以短时间使用,但如果合法用户下次交换新签名,则无法换新签名,因为令牌有效期很短。这种方式更安全。

如果没有黑客,普通用户也需要定期交换新令牌,比如每30分钟,这就像自动登录一样。额外负载不高,我们可以调整应用程序的到期时间。

来源:http://www.jianshu.com/p/b11accc40ba7


9
投票

这并没有完全回答你关于Spring框架的问题,但是这篇文章讨论了为什么如果你需要撤销JWT的能力,你可能不想首先使用JWT,而是使用常规,不透明的承载令牌。

https://www.dinochiesa.net/?p=1388


7
投票

撤销JWT的一种方法是利用分布式事件系统,该系统在刷新令牌被撤销时通知服务。当撤销刷新令牌并且其他后端/服务侦听事件时,身份提供者广播事件。当收到事件时,后端/服务会更新本地缓存,该缓存维护一组已撤销刷新令牌的用户。

然后,每当验证JWT以确定是否应该撤销JWT时,都检查该高速缓存。这完全基于JWT的持续时间和各个JWT的到期时刻。

这篇文章Revoking JWTs说明了这个概念,并在Github上有一个示例应用程序。


-3
投票

以下是撤销JWT访问令牌的步骤:

  1. 登录时,发送2个令牌(访问令牌,刷新令牌)以响应客户端
  2. 访问令牌将具有较少的到期时间,并且刷新将具有较长的到期时间。
  3. 客户端(前端)将刷新令牌存储在其本地存储中并访问令牌中的令牌。
  4. 客户端将使用访问令牌来调用apis。但是当它到期时,从本地存储中选择刷新令牌并调用auth server api以获取新令牌。
  5. 您的auth服务器将暴露api,它将接受刷新令牌并检查其有效性并返回新的访问令牌。
  6. 刷新令牌过期后,用户将被注销。

如果您需要更多详细信息,请告诉我,我也可以分享代码。

© www.soinside.com 2019 - 2024. All rights reserved.