如何撤销JWT令牌?

sab*_*abu 62 oauth-2.0 spring-security-oauth2

我正在使用spring oauth2和JWT令牌.有人可以帮助我如何撤销JWT令牌?

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

Joã*_*elo 74

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

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

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

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

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

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

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

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

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

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

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

一个有趣的参考

本文解释另一种方法:黑名单JWT 它包含一些有趣的实践和模式,后面是RFC7523

  • 文本对此不是很清楚,但是是的,我正在谈论仅为已撤销的按值令牌存储某些内容,并且仅在未达到它们的正常到期时间之前。每个令牌都会像往常一样被验证,然后会进行额外的检查,看看它是否没有被撤销。 (2认同)

Hua*_*ghq 18

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

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

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

table auth_tokens(
    user_id,
    jwt_hash,
    expire
)
Run Code Online (Sandbox Code Playgroud)

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

  • 该解决方案的主要缺点是同一时间只能有一个用户登录。 (2认同)
  • 如果用户停止使用系统并且黑客交换了新的令牌怎么办?听起来黑客可以继续使用和交换令牌,直到用户再次登录。恶心。 (2认同)
  • 这是一个*不应该被赞成的答案。如前所述,提议的答案将黑名单与刷新混合在一起,这意味着令牌现在既是“有状态的”又是“单例的”(仅限单点登录),这两者都完全违反了 JWT 原则。然而,所提出的解决方案仍然存在依赖过期的问题(留下一个主要弱点),同时引入新的解决方案(单点登录)。因此,这比简单的 auth jwt + 刷新令牌和黑名单机制更糟糕。说实话:它也不是最简单的实现(可能存在错误)。 (2认同)

dz9*_*902 12

对于谷歌员工:

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

  • JWT 是否有任何替代方案既可以支持令牌撤销,又可以用于实现纯无状态身份验证? (2认同)

Ian*_*lor 9

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

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


小智 7

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

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

这篇文章,撤销JWT,说明了这个概念,并在Github上有一个示例应用程序.

  • @DenverCoder9 也许令牌已成功撤销 (3认同)
  • “撤销 JWT”链接现在返回 404。 (2认同)