如何在Oauth2中撤销RefreshToken并同时使AccessToken无效

本文关键字:无效 AccessToken RefreshToken Oauth2 | 更新日期: 2023-09-27 18:24:56

我正在使用Owin-Outh2开发单页应用程序(AngularJS+.Net MVC Json Rest API)的身份验证流(授权和资源服务器相同)。

我选择Bearer Token路由而不是传统的cookie+会话,因为我想保持无状态,也因为相同的Api将被移动应用程序使用,其中令牌的问题比cookie小。

这是简化的流程:

  • 用户向服务器提交用户名/密码(通过HTTPS向TokenProvider路由)
  • Owin创建一个AccessToken,声明包含生成的GUID(将表示类似会话Id的东西)和一些其他声明
  • Owin创建了一个RefreshToken
  • 服务器在RefreshToken表中创建一个包含以下字段的条目:

GUID(PK)|RefreshToken|Ticket|DateIssue|DateExpire|DateEnd

  • 服务器同时提供AccessToken和CCD_ 5发送给客户端。

  • 客户端将AccessTokenRefreshToken都存储到SessionStorage中。

  • 客户端使用AccessToken访问API。

AngularJS检测到AccessToken即将过期时,缓冲所有请求并发出grant_type refresh_token request
服务器使用客户端提供的RefreshToken和:

  • 检查Db中的刷新令牌是否仍然有效(DateExpire > GetTime() And DateEnd is Null
  • 从Db获取票证
  • 从票证创建访问令牌
  • 使用新的日期、新的RefreshToken和新的Ticket更新DB条目(注意:GUID保持不变)

当客户端访问注销服务器端时,从已登录用户的身份声明中读取的GUID用于使表上的条目无效(DateEnd = GetTime()
客户端的两个令牌都从SessionStorage中移除。

通过这种方式,我可以撤销拒绝任何其他请求以获得新的AccessTokenRefreshToken

这种方法的问题是,当授权被撤销时(即:RefreshToken在DB上无效)存在一个时间窗口,但AccessToken仍然有效(尽管时间帧有限)。

我想做的是在每个请求上检查AccessToken的有效性,从用户身份声明中获取GUID,并点击数据库来检查该特定GUID的刷新令牌是否仍然有效。

尽管使查询执行O(1)非常简单,但单点故障本身可能会对系统的可扩展性和性能产生负面影响。

你知道缓解这个问题的另一种方法吗?你认为我的方法有什么缺陷吗?

如何在Oauth2中撤销RefreshToken并同时使AccessToken无效

您的方法没有错,与我之前在博客中提到的方法完全相同,但我建议在发送访问令牌时不要进行任何DB检查。

为什么不发布短时间访问令牌,即(30分钟),并且在撤销刷新令牌后等待访问令牌生存期到期。在客户端上,您可以从客户端的本地存储中清除刷新令牌和访问令牌。