我正在使用Owin Oauth2开发单页面应用程序(AngularJS + .Net MVC Json Rest API)的验证流程(授权和资源服务器是相同)。如何在Oauth2中同时撤销RefreshToken并使AccessToken失效
我选择了传统cookie +会话中的承载令牌路由,因为我想保持无状态,也是因为相同的Api将被移动应用使用,其中令牌的问题少于Cookie。
这是简化的流程图:
- 用户(通过HTTPS POST到 TokenProvider路线)提交用户名/密码到服务器
- Owin创建
AccessToken
用含有 生成GUID一个如权利要求(这将表示类似于会话ID)和其他一些索赔。 - Owin创建
RefreshToken
。 - 服务器会在
RefreshToken
表具有以下字段中输入:
GUID(PK)| RefreshToken |订票| DateIssued | DateExpire | DateEnd
服务器提供了两个
AccessToken
和RefreshToken
给客户端。客户端将
AccessToken
和RefreshToken
存储到SessionStorage中。客户端通过
AccessToken
访问Api。
当AngularJS检测到的accessToken接近到期时,它缓冲所有请求和问题grant_type refresh_token request
;
服务器使用客户端提供的RefreshToken
和:
- 检查该刷新令牌还是从数据库有效(
DateExpire > GetTime() And DateEnd is Null
) - 注意到从数据库门票
- 门票创建一个的accessToken
- 使用新日期更新db条目,新的
RefreshToken
和新票(注意:GUID保持不变)
当客户端登录注销服务器端时,从登录用户的身份声明中读取的GUID用于使表中的条目无效(DateEnd = GetTime()
)。
客户端两个令牌都从SessionStorage
中删除。
通过这种方式,我可以撤消RefreshToken
拒绝任何其他请求获得新的AccessToken
。
这种方法的问题是,授权被撤销时存在时间窗口(即:RefreshToken
在数据库上无效),但AccessToken
仍然有效(虽然对于有限的时间帧)。
我想要做的是检查每个请求上的AccessToken
的有效性,从用户身份声明中获取GUID并敲击db以检查该特定GUID的Refresh Token是否仍然有效。
尽管使查询执行O(1)非常简单,但单点故障本身可能会对系统的可伸缩性和性能产生负面影响。
您是否知道另一种方法来缓解此问题,并且您是否看到我的方法中存在任何缺陷?
仅供我感兴趣我在阻止电子邮件访问移动设备时遇到了Office 365 Exchange的此问题。在访问令牌到期之前,用户的电子邮件帐户不会被锁定,在这种情况下完全是一个小时。 – peterincumbria 2017-08-21 08:14:57