如何在Oauth2中同时撤销RefreshToken并使AccessToken无效
我正在使用Owin Oauth2(授权和资源服务器是相同的)开发单页面应用程序(AngularJS + .Net MVC Json Rest API)的身份validation流程。
我在传统的cookie +会话中选择了Bearer Token路由,因为我希望保持无状态,并且因为移动应用程序将使用相同的Api,其中令牌的问题少于cookie。
这是简化的流程:
- 用户将用户名/密码提交给服务器(通过Https POST到TokenProvider路由)
- Owin创建一个
AccessToken
,其AccessToken
包含生成的GUID(代表会话ID)和其他一些声明。 - Owin创建了一个
RefreshToken
。 - Server在
RefreshToken
表中创建一个条目,其中包含以下字段:
GUID(PK)| RefreshToken |订票| DateIssued | DateExpire | DateEnd
-
Server为客户端提供
AccessToken
和RefreshToken
。 -
客户端将
AccessToken
和RefreshToken
存储到SessionStorage中。 -
客户端使用
AccessToken
访问Api。
当AngularJS检测到AccessToken即将到期时,它会缓冲所有请求并发出grant_type refresh_token request
;
server使用客户端提供的RefreshToken
,并且:
- 从Db检查刷新令牌是否仍然有效(
DateExpire > GetTime() And DateEnd is Null
) - 从Db拿到机票
- 从Ticket创建AccessToken
- 使用新Dates,新
RefreshToken
和新Ticket更新db条目(注意:GUID保持不变)
当客户端访问注销服务器端时,从已记录用户的身份声明中读取的GUID用于使表上的条目无效( DateEnd = GetTime()
)。
客户端两个令牌都从SessionStorage
中删除。
通过这种方式,我可以撤销RefreshToken
拒绝任何其他请求获取新的AccessToken
。
这种方法的问题在于,授权被撤销时存在一个时间窗口(即:在DB上无效的RefreshToken
)但是AccessToken
仍然有效(尽管在有限的时间范围内)。
我想要做的是检查每个请求上的AccessToken
的有效性,从用户身份声明中获取GUID并命中数据库以检查该特定GUID的刷新令牌是否仍然有效。
尽管使查询执行O(1)非常简单,但单点故障本身可能会对系统的可伸缩性和性能产生负面影响。
你知道另一种缓解这个问题的方法吗?你看到我的方法有什么缺陷吗?
您的方法没有任何问题,它与我之前发表过博客的方法完全相同,但我建议您在发送访问令牌时不要进行任何数据库检查。
为什么你不发出短期访问令牌,即(30分钟),并等到撤销刷新令牌后访问令牌的生命周期到期。 在客户端上,您可以从客户端本地存储中清除刷新令牌和访问令牌。
- 如何在ASP.NET上设置treeview的childnode postback false?
- 有没有更快的方法来检查外部网页是否存在?
- 隐藏BoundField但仍能用C#获取值
- 动态创建按钮以调用方法并传入参数
- ASP.NET INamingContainer – 可选前缀
- 将值数组发送到Oracle过程以在WHERE IN子句中使用
- ASP.NET Web应用程序 – 在部署时,System.Speech.dll对象未设置为对象的实例
- 如何在runAllManagedModulesForAllRequests设置为true的情况下为IIS 7中的flv文件禁用gzip压缩?
- 存储过程返回到C#.Net中的DataSet