如何撤销JWT令牌?

时间:2015-08-10 12:04:24

标签: oauth-2.0 spring-security-oauth2

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

如上所述 http://projects.spring.io/spring-security-oauth/docs/oauth2.html,撤销由刷新令牌完成。但它似乎没有用。

7 个答案:

答案 0 :(得分:65)

一般来说,最简单的答案就是说你不能撤销JWT令牌,但这根本不是真的。诚实的答案是,支持JWT撤销的成本足以让大部分时间不值得,或明显重新考虑替代JWT。

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

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

  

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

     

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

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

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

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

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

  

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

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

有趣的参考资料

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

答案 1 :(得分:9)

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

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

答案 2 :(得分:7)

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

每当验证JWT时,都会检查此缓存,以确定是否应撤销JWT。这完全基于JWT的持续时间和单个JWT的到期时刻。

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

答案 3 :(得分:2)

对于 Google 员工:

  • 如果您实施纯粹的无状态身份验证,则无法撤销令牌,因为令牌本身是唯一的真实来源
  • 如果您在服务器上保存已撤销令牌 ID 的列表并根据列表检查每个请求,那么它本质上是有状态身份验证的一种变体
  • 像 Cognito 这样的 OAuth2 提供商提供了一种“注销”用户的方法,但是,它只是真正撤销刷新令牌,刷新令牌通常是长期存在的,可以多次使用以生成新的访问令牌,因此必须撤销;现有的访问令牌在到期前仍然有效

答案 4 :(得分:0)

如何存储JWT令牌并将其引用给数据库中的用户?在执行JWT比较之后,通过使用额外的数据库联接扩展后端应用程序中的Guards / Security Systems,您实际上可以通过从数据库中删除或软删除来“撤消”它。

答案 5 :(得分:-1)

我找到了解决问题的一种方法,How to expire already generated existing JWT token using Java?

在这种情况下,我们需要使用任何数据库或内存,

第1步::首次为用户生成令牌后,将其与令牌一起存储在数据库中,并为“ issuedAt()”时间。

我以JSON格式将其存储在数据库中,

例如: {"username" : "username", "token" : "token", "issuedAt" : "issuedAt"}

步骤2:一旦您获得了具有令牌要验证的同一用户的Web服务请求,请从令牌中获取“ issuedAt()”时间戳并进行比较带有已存储的(数据库/内存中)发布的时间戳。

步骤3:如果存储的已发布时间戳是新的(使用after()/ before()方法),则返回令牌无效(在这种情况下,我们实际上并未使令牌过期)将停止提供对该令牌的访问权限。

这就是我解决问题的方式。

答案 6 :(得分:-3)

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

  1. 登录时,请在其中发送2个令牌(访问令牌,刷新令牌) 对客户的回应
  2. 访问令牌的有效时间将更少,而刷新将具有 有效期长。
  3. 客户端(前端)将刷新令牌存储在其本地存储中     并访问Cookie中的令牌。
  4. 客户端将使用访问令牌来调用api。但是当它 过期,请从本地存储中选择刷新令牌,然后致电身份验证 服务器api以获取新令牌。
  5. 您的身份验证服务器将公开一个可以接受的api 刷新令牌并检查其有效性并返回新的访问权限 令牌。
  6. 刷新令牌过期后,用户将注销。

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