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。

640?wx_fmt=jpeg

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

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

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

三.自定义Token失效机制

640?wx_fmt=png

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是可能会有这样的问题,所以在此发表了我的一个观点,希望能给你参考,后续的文章我会根据这个想法来实现。

原文地址:https://www.cnblogs.com/stulzq/p/9678501.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用.Net Core实现FNV分布式hash一致性算法

说到FNV哈希算法不得不提Memcached,我们先简单介绍一下Memcached。MemcachedMemcached分为客户端与服务端,Memcached是服务端,服务端本身不提供分布式实现,只是一个单独的k-v缓存;Memcached的分布式是在客户端类库中实…

[XSY4197] Snow(树形DP)

我们在树上的每个点iii上放aia_iai​个小点,初始时先让每个点单独减,这样要花费aia_iai​之和的次数。 然后尝试把某些减合并。一个点上面的小点至多可以向两个相邻的小点连边(这两个小点不能在同一个点上)。每连一条边&#xff…

Followme Devops实践之路

引言天下武功,唯快不破想要提高开发团队效率,势必要有一套完整而成熟的开发流程方案,除了sprint迭代开发模式之外,还有近几年流行的devops流程,都是可以大幅度提高开发效率的工具. 我们团队也不断探索、实践,最终形成了现有的一套体系&#x…

基环树小记

概念 基环树就是有n个点n条边的图(比树多出现一个环)。 特殊形态的基环树 无向树(N点N边无向图) 外向树(每个点只有一条入边) 内向树(每个点只有一条出边) 以上三种树有十分优秀的性质,就是可以直接将环作为根。就可以对每个环的子树进行单…

利用BenchmarkDotNet 测试 .Net Core API 同步和异步方法性能

事由:这两天mentor给我布置了个任务让我用BenchmarkDotNet工具去测试一下同一个API 用同步和异步方法写性能上有什么差别。顺带提一下:啊啊啊啊 等我仔细看文档的时候文档 发现它让我用Release的模式去运行benchmark。 emmm...其实我之前一直在用Debug模…

MATLAB线性规划相关函数用法

一.线性规划的Matlab标准形式及软件求解 1. MATLAB中规定线性规划的标准形式为 其中c和 x为n 维列向量, A、 Aeq 为适当维数的矩阵,b 、beq为适当维数的列向量。 (Aeq 对应约束条件中等式约束的系数矩阵,A为约不等式约束的系数矩…

.NET Core 出得云端入得本地,微软让跨平台应用勇敢表达

地铁公交的上班路上、咖啡馆里等人的时候,这些碎片化时间都是现代人学习和充电的机会,根据第42次CNNIC中国互联网发展状况统计报告,截至2018年6月,网络文学用户规模已达4.06亿,占网民总体50.6%;手机网络文学…

【每日一题】7月3日精讲—毒瘤xor

【每日一题】7月3日精讲—毒瘤xor 时间限制:C/C 1秒,其他语言2秒 空间限制:C/C 32768K,其他语言65536K Special Judge, 64bit IO Format: %lld文章目录题目描述题解:代码:题目描述 输入描述: 第一行一个整…

了解改良圈算法

一.相关知识——Hamilton圈 什么是Hamilton圈? 哈密顿图(哈密尔顿图)(英语:Hamiltonian path,或Traceable path)是一个无向图,由天文学家哈密顿提出,由指定的起点前往指…

ASP.NET Core Middleware

中间件(Middleware)是ASP.NET Core中的一个重要特性。所谓中间件就是嵌入到应用管道中用于处理请求和响应的一段代码。ASP.NET Core Middleware可以分为两种类型:Conventional MiddlewareIMiddlewareConventional Middleware这种中间件没有实现特定的接口或者继承特…

NOIP复健计划——动态规划

树形DP [POI2011] DYN-Dynamite 二分KKK check(mid): 能否选出mmm个点,使得 ∀i为关键点,Minjisselected{dis(i,j)}≤mid\forall i为关键点,Min_{j\ is\ selected}\{dis(i,j)\}\leq mid∀i为关键点,Minj is selecte…

【每日一题】7月6日精讲—平衡二叉树

来源:牛客网: 文章目录题目描述题解:代码:时间限制:C/C 1秒,其他语言2秒 空间限制:C/C 1048576K,其他语言2097152K 64bit IO Format: %lld题目描述 平衡二叉树,顾名思义就…

MATLAB灰色预测

一.灰色预测 1.灰色系统下的灰色预测 <1>什么是灰色系统&#xff1f; 所谓的灰色系统其实就是夹杂在白色系统和黑色系统之中的一种系统&#xff0c;而白色系统就是全部信息已知的系统&#xff0c;黑色系统就是全部信息未知的系统。所以&#xff0c;夹在这两种系统中间…

ASP.NET Core 中的依赖注入

什么是依赖注入软件设计原则中有一个依赖倒置原则&#xff08;DIP&#xff09;&#xff0c;为了更好的解耦&#xff0c;讲究要依赖于抽象&#xff0c;不要依赖于具体。而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖注入(DI)。什么是依…

【每日一题】7月7日题目精讲—最短路

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 给一个连通图&#xff0c;每次询问…

【活动(广州)】office365的开发者训练营

Office 365每月有超过1亿的商业活跃用户&#xff0c;是现有最大的生产力服务。Office 365为开发人员提供了一个令人难以置信的机会&#xff0c;包括业务关键数据和数百万用户&#xff0c;以及一个旨在让人们保持工作流程的平台。作为一名开发人员&#xff0c;您可以使用每天使用…

牛客网【每日一题】7月8日 Alliances

来源&#xff1a;牛客网 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 5秒&#xff0c;其他语言10秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 树国是一个有n个城市的国家&#xff0c;城市编号…

Ocelot简易教程(四)之请求聚合以及服务发现

上篇文章给大家讲解了Ocelot的一些特性并对路由进行了详细的介绍&#xff0c;今天呢就大家一起来学习下Ocelot的请求聚合以及服务发现功能。希望能对大家有所帮助。作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9695639.html请求聚合Ocelot允…

邓公数据结构C++语言版学习笔记1

1. 对于计算幂2n2^n2n的算法优化 暴力算法时间复杂度O(n)O(n)O(n) __int64 power2BF_I(int n) //幂函数2^n算法&#xff08;蛮力迭代版&#xff09;&#xff0c;n > 0{ __int64 pow 1; //O(1)&#xff1a;累积器刜始化为2^0while (0 < n --) //O(n)&#xff1a;迭代n轮…

HttpClientFactory系列二:集成Polly处理瞬态故障

前言&#xff1a;最近&#xff0c;同事在工作中遇到了使用HttpClient,有些请求超时的问题&#xff0c;辅导员让我下去调研一下&#xff0c;HttpClinet的使用方式已经改成了之前博客中提到的方式&#xff0c;问题的原因我已经找到了&#xff0c;就是因为使用了伪异步&#xff0c…