原文:IdentityServer4实战 - 谈谈 JWT Token 的安全策略

一.前言

众所周知,IdentityServer4 默认支持两种类型的 Token,一种是 Reference Token,一种是 JWT Token 。前者的特点是 Token 的有效与否是由 Token 颁发服务集中化控制的,颁发的时候会持久化 Token,然后每次验证都需要将 Token 传递到颁发服务进行验证,是一种中心化的比较传统的验证方式。JWT Token 的特点与前者相反,每个资源服务不需要每次都要都去颁发服务进行验证 Token 的有效性验证,该 Token 由三部分组成,其中最后一部分包含了一个签名,是在颁发的时候采用非对称加密算法(最新的JWT Token)进行数据签名的,保证了 Token 的不可篡改性,保证了安全,与颁发服务的交互,仅仅是获取公钥用于验证签名,且该公钥获取以后可以自己缓存,持续使用,不用再去交互获得,除非Token包含的 keyid 对应的 公钥没被缓存(新的),就会再次向颁发服务获取。我画了一张流程图,大家可以去查看:https://www.cnblogs.com/stulzq/p/9226059.html

这里说一下我在文章说所说的名词:

颁发服务:即生成Token的服务。

资源服务:提供给用户访问的API资源

二.JWT Token 的安全问题

前言中有过叙述,JWT 类型的 Token 在验证的时候,无需依靠颁发服务来验证 Token 的有效性,是一种去中心化的验证方式,这就意味着颁发服务无法集中控制 Token。假如 Token 暴露以后,在 Token 有效期内,将会一直被人恶意使用,这时候该怎么办呢?这里主要从两个方面来讲,一个是尽量避免被恶意获取Token,一个是被恶意获取了怎么控制失效。请听下面分解。

1.使用 HTTPS

此种方式是避免被人获取恶意获取Token。

HTTPS 在传输数据时,数据内容是加密的,可以有效避免中间人攻击,所以在使用 JWT Token 的程序建议都采用HTTPS。

2.添加自定义Token失效机制

此种方式是被恶意获取了怎么控制失效。

因为 IdentityServer4 对 JWT Token,默认是没有控制失效的机制的,所以如果我们想添加这种机制,只有我们自定义,下一节做详细介绍。

三.自定义Token失效机制

1.简单黑名单模式

顾名思义,就是添加一个 Token 黑名单,这个黑名单建议存在诸如 Redis 等分布式缓存,数据库等介质,可以让所有资源服务共同访问。不推荐添加在资源服务本地缓存,如果这样做,那么每次添加黑名单还需要同步到每个资源服务。每个资源服务在每次验证Token的时候需要查询一下黑名单,如果在黑名单里面,即 Token 无效。

2.进阶黑名单模式

前面小节的 【简单黑名单模式】 有一个非常大的弊端,就是每个 Token 验证时都需要去验证是否在黑名单,正常情况下,我们正常的Token 是占绝大多数的,如果用此种机制,那么对资源是一种很大的浪费。那么我们需要设立一种机制,来让我们认为 可疑 的Token进行黑名单验证,那么如何来判断Token是否可疑呢,我这里想了一种方式。

如何判断 Token 是否可疑:

我们在生成Token的时候,可以添加自定义 Claim (身份信息单元),那么我们可以参考网站登录的安全机制,那么我们可以添加一个用户ip的Claim,这样我们生成的Token都会携带用户生成Token时的IP,我们每次验证Token是否有效时,就可以根据客户端来源IP与Token携带的IP进行匹配,如果匹配不上,那么该Token我们就可以认为是可疑的,从而进行黑名单的验证。

该方式相对于前面的 【简单黑名单模式】模式算是一个比较好的进阶了。

在这里,我们还需要考虑到IP作为用户的私密信息,我们将IP放入Token时,需要对IP进行加密。因为 JWT Token 前两部分,仅仅是 base64 Encode 而已。

Claim 详解请参考 http://www.cnblogs.com/stulzq/p/8726002.html

3.强化黑名单模式

无论是【简单黑名单模式】还是【进阶黑名单模式】,我们在对比黑名单时是对token进行完全比对,这样的方式,在某些场景就存在局限性,比我想让该用户在某某时间以前颁发的Token都算作黑名单。所以我们在判断黑名单时可以根据用户id以及token颁发时间来判断。如果让规则自动失效?我们可以用前面设定的 token颁发时间加上我们颁发服务设置的token有效时间就等于规则失效时间。

4.将Token添加进黑名单的方式

我们前面设立了黑名单模式,那么我们的Token何时加入黑名单呢,难道让用户说,我的 Token 被盗了,你把我的 Token加入黑名单吧,这肯定不现实。我们可以在退出登录时,就自动往黑名单添加一条规则,采用【强化黑名单模式】添加用户id以及当前时间作为token颁发时间来验证。比如用户id1000,此用户在 2018-09-20 12:11 退出,我们就可以添加一条规则 userid=1000,tokenissuetime=2018-09-20 12:11 ,该规则表示只要用户id为1000的并且token颁发时间小于2018-09-20 12:11的token,都被算作黑名单token。

这时有人可能会说,这个token如果还是这个用户再次拿来使用,那还是有效的,你这个怎么没让他失效呢?我们设立黑名单模式就是为了避免用户的还在有效期的Token被他人恶意使用。对于用户自己来说,这个问题就无关紧要了。

5.全部 Token 失效的机制。

全部Token失效的方式,目前我想了两种:

1.更换颁发服务的密钥对,并且重启所有资源服务(资源服务获取的公钥默认存在内存,重启可以丢失)。这样原本的Token在验证时,将会找不到对应的公钥,导致验签失败从而Token无效。

2.类似于前面【强化黑名单模式】的验证黑名单的方式,我们可以在验证Token的流程中加两个配置,一个是控制这种配置是否开启的开关,一个是某个时间,规则就是如果在这个时间以前颁发Token全部算作无效Token。这种就需要资源服务支持热加载配置,从而避免重启资源服务。

我个人推荐第二种方式。

四.其他解决方案

这里的内容是根据评论整理的,我个人的想法不可能面面俱到,所以整理了一下评论里比较不错的方案:

Savorboard:

JWT 的最佳实践是遵循默认的过期策略(15分钟过期), 他能够有效的保证Token的有效性。 刷新Token是为了保证身份验证的服务端与授予令牌的客户端在访问权限方面保持一致,比如Claim里可能包含最新的访问权限,这是一个必要且必须的过程。

所以,频繁的15分钟刷新令牌是有必要的,这并不足以对服务器的性能产生很大的影响。

五.写在最后

文中所诉是总结了我长久以来的想法,token加入ip还有根据id和颁发时间验证黑名单都是我今天无意间想到的。如果你阅读了本文有什么不明白或者你认为有改进的地方,或者更好的地方,欢迎在评论与我交流。本文的问题,有很多人问过我,也讨论了不少,我相信很多人在使用ids4是可能会有这样的问题,所以在此发表了我的一个观点,希望能给你参考,后续的文章我会根据这个想法来实现。

IdentityServer4实战 - 谈谈 JWT Token 的安全策略的更多相关文章

  1. IdentityServer4实战 - 谈谈 JWT 的安全策略

    一.前言 众所周知,IdentityServer4 默认支持两种类型的 Token,一种是 Reference Token,一种是 JWT Token .前者的特点是 Token 的有效与否是由 To ...

  2. 关于 IdentityServer4 中的 Jwt Token 与 Reference Token

    OpenID Connect(Core),OAuth 2.0(RFC 6749),JSON Web Token (JWT)(RFC 7519) 之间有着密不可分联系,对比了不同语言的实现,还是觉得 I ...

  3. IdentityServer4实战 - JWT Token Issuer 详解

    原文:IdentityServer4实战 - JWT Token Issuer 详解 一.前言 本文为系列补坑之作,拖了许久决定先把坑填完. 下文演示所用代码采用的 IdentityServer4 版 ...

  4. ASP.NET Core 实战:基于 Jwt Token 的权限控制全揭露

    一.前言 在涉及到后端项目的开发中,如何实现对于用户权限的管控是需要我们首先考虑的,在实际开发过程中,我们可能会运用一些已经成熟的解决方案帮助我们实现这一功能,而在 Grapefruit.VuCore ...

  5. IdentityServer4实战 - JWT Issuer 详解

    一.前言 本文为系列补坑之作,拖了许久决定先把坑填完. 下文演示所用代码采用的 IdentityServer4 版本为 2.3.0,由于时间推移可能以后的版本会有一些改动,请参考查看,文末附上Demo ...

  6. IdentityServer4实战 - AccessToken 生命周期分析

    一.前言 IdentityServer4实战这个系列主要介绍一些在IdentityServer4(后文称:ids4),在实际使用过程中容易出现的问题,以及使用技巧,不定期更新,谢谢大家关注.使用过id ...

  7. IdentityServer4实战 - 基于角色的权限控制及Claim详解

    一.前言 大家好,许久没有更新博客了,最近从重庆来到了成都,换了个工作环境,前面都比较忙没有什么时间,这次趁着清明假期有时间,又可以分享一些知识给大家.在QQ群里有许多人都问过IdentityServ ...

  8. IdentityServer4 实战文档

    一.前言 IdentityServer4实战这个系列主要介绍一些在IdentityServer4(后文称:ids4),在实际使用过程中容易出现的问题,以及使用技巧,不定期更新,谢谢大家关注.这些问题. ...

  9. Spring Cloud OAuth2.0 微服务中配置 Jwt Token 签名/验证

    关于 Jwt Token 的签名与安全性前面已经做了几篇介绍,在 IdentityServer4 中定义了 Jwt Token 与 Reference Token 两种验证方式(https://www ...

随机推荐

  1. 自旋锁spinlock解析

    1 基础概念 自旋锁与相互排斥锁有点类似,仅仅是自旋锁不会引起调用者睡眠.假设自旋锁已经被别的运行单元保持.调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁."自旋"一词就 ...

  2. 3、Unicode\UTF-8\GBK 区别和联系

    字符编码:Unicode和UTF-8之间的关系 可以参考下面blog:https://blog.csdn.net/xiaolei1021/article/details/52093706/ 这篇文章写 ...

  3. 9、LCD驱动程序框架

    linux-3.4.2\drivers\video\S3C2410fb.c(内核自带驱动程序) fbmem.c是LCD驱动程序顶层框架文件,是一个通用的文件,在初始化init函数中会注册一个字符设备, ...

  4. CSS边框作图

    原文 简书原文:https://www.jianshu.com/p/537a878304f2 大纲 1.border-style的值 2.利用border作图——基本图形 3.利用border作图—— ...

  5. ios开发核心动画七:核心动画与UIView动画的区别

    /** UIView与核心动画区别?(掌握) 1.核心动画只作用在layer. 2.核心动画看到的都是假像,它并没有去修改UIView的真实位置. 什么时候使用核心动画? 1.当不需要与用户进行交互, ...

  6. PatentTips - 在物联网中进行数据过滤的方法和装置

    背景技术 [0001] 本发明涉及物联网,特别涉及在物联网进行数据过滤的方法和装置. [0002] 物联网是新一代信息技术的重要组成部分,特指物物相连的网络.具体地,物联网是指通过各种信息传感设备,如 ...

  7. 5.8 pprint--美观地打印数据

    pprint模块提供了一个美观地打印Python数据结构的方式.假设是要格式化的数据结构里包括了非基本类型的数据,有可能这样的数据类型不会被载入.比方数据类型是文件.网络socket.类等.本模块格式 ...

  8. 【33.33%】【codeforces 552B】Vanya and Books

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  9. MCMC:Gibbs 采样(matlab 实现)

    MCMC: The Gibbs Sampler 多元高斯分布的边缘概率和条件概率 Marginal and conditional distributions of multivariate norm ...

  10. Material Designer的低版本兼容实现 —— ActivityOptionsCompat

    http://www.bubuko.com/infodetail-460163.html