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

我选择了不记名 token 路由而不是传统的 cookie+ session ,因为我想保持无状态,也因为相同的 Api 将被移动应用程序使用,其中 token 的问题比 cookie 的问题少。

这是简化的流程:

  • 用户向服务器提交用户名/密码(POST over Https 到
    TokenProvider 路由)
  • Owin 创建一个带有声明的 AccessToken生成的 GUID(将表示类似于 session ID 的内容)和其他一些声明。
  • Owin 创建一个 RefreshToken
  • 服务器在 RefreshToken 表中创建一个包含以下字段的条目:


  • 服务器同时提供 AccessTokenRefreshToken 给客户端。
  • 客户端将 AccessTokenRefreshToken 都存储到 SessionStorage 中。
  • 客户端使用 AccessToken 访问 Api。

  • 当 AngularJS 检测到 AccessToken 即将过期时,它会缓冲所有请求并发出 grant_type refresh_token request
    服务器使用客户端提供的 RefreshToken 并且:
  • 从 Db ( DateExpire > GetTime() And DateEnd is Null )
  • 检查刷新 token 是否仍然有效
  • 从 Db
  • 获取票证
  • 从票证创建 AccessToken
  • 使用新的日期、新的 RefreshToken 和新的票证更新数据库条目(注意:GUID 保持不变)

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

    通过这种方式,我可以撤销 RefreshToken 拒绝任何其他获取新 AccessToken 的请求。

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

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

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

    您是否知道另一种缓解此问题的方法,您是否发现我的方法有任何缺陷?

    最佳答案

    您的方法没有任何问题,它与我之前提到的 blogged 方法非常相同,但我的建议是在您发送访问 token 时不要进行任何数据库检查。

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

    关于c# - 如何在Oauth2中同时撤销RefreshToken和使AccessToken失效,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26071758/

    10-13 08:00