IdentityServer4实战 - 谈谈 JWT Token 的安全策略
一.前言
眾所周知,IdentityServer4 默認(rèn)支持兩種類(lèi)型的 Token,一種是 Reference Token,一種是 JWT Token 。前者的特點(diǎn)是 Token 的有效與否是由 Token 頒發(fā)服務(wù)集中化控制的,頒發(fā)的時(shí)候會(huì)持久化 Token,然后每次驗(yàn)證都需要將 Token 傳遞到頒發(fā)服務(wù)進(jìn)行驗(yàn)證,是一種中心化的比較傳統(tǒng)的驗(yàn)證方式。JWT Token 的特點(diǎn)與前者相反,每個(gè)資源服務(wù)不需要每次都要都去頒發(fā)服務(wù)進(jìn)行驗(yàn)證 Token 的有效性驗(yàn)證,該 Token 由三部分組成,其中最后一部分包含了一個(gè)簽名,是在頒發(fā)的時(shí)候采用非對(duì)稱加密算法(最新的JWT Token)進(jìn)行數(shù)據(jù)簽名的,保證了 Token 的不可篡改性,保證了安全,與頒發(fā)服務(wù)的交互,僅僅是獲取公鑰用于驗(yàn)證簽名,且該公鑰獲取以后可以自己緩存,持續(xù)使用,不用再去交互獲得,除非Token包含的 keyid 對(duì)應(yīng)的 公鑰沒(méi)被緩存(新的),就會(huì)再次向頒發(fā)服務(wù)獲取。我畫(huà)了一張流程圖,大家可以去查看:https://www.cnblogs.com/stulzq/p/9226059.html
這里說(shuō)一下我在文章說(shuō)所說(shuō)的名詞:
頒發(fā)服務(wù):即生成Token的服務(wù)。
資源服務(wù):提供給用戶訪問(wèn)的API資源
二.JWT Token 的安全問(wèn)題
前言中有過(guò)敘述,JWT 類(lèi)型的 Token 在驗(yàn)證的時(shí)候,無(wú)需依靠頒發(fā)服務(wù)來(lái)驗(yàn)證 Token 的有效性,是一種去中心化的驗(yàn)證方式,這就意味著頒發(fā)服務(wù)無(wú)法集中控制 Token。假如 Token 暴露以后,在 Token 有效期內(nèi),將會(huì)一直被人惡意使用,這時(shí)候該怎么辦呢?這里主要從兩個(gè)方面來(lái)講,一個(gè)是盡量避免被惡意獲取Token,一個(gè)是被惡意獲取了怎么控制失效。請(qǐng)聽(tīng)下面分解。
1.使用 HTTPS
此種方式是避免被人獲取惡意獲取Token。
HTTPS 在傳輸數(shù)據(jù)時(shí),數(shù)據(jù)內(nèi)容是加密的,可以有效避免中間人攻擊,所以在使用 JWT Token 的程序建議都采用HTTPS。
2.添加自定義Token失效機(jī)制
此種方式是被惡意獲取了怎么控制失效。
因?yàn)?IdentityServer4 對(duì) JWT Token,默認(rèn)是沒(méi)有控制失效的機(jī)制的,所以如果我們想添加這種機(jī)制,只有我們自定義,下一節(jié)做詳細(xì)介紹。
三.自定義Token失效機(jī)制
1.簡(jiǎn)單黑名單模式
顧名思義,就是添加一個(gè) Token 黑名單,這個(gè)黑名單建議存在諸如 Redis 等分布式緩存,數(shù)據(jù)庫(kù)等介質(zhì),可以讓所有資源服務(wù)共同訪問(wèn)。不推薦添加在資源服務(wù)本地緩存,如果這樣做,那么每次添加黑名單還需要同步到每個(gè)資源服務(wù)。每個(gè)資源服務(wù)在每次驗(yàn)證Token的時(shí)候需要查詢一下黑名單,如果在黑名單里面,即 Token 無(wú)效。
2.進(jìn)階黑名單模式
前面小節(jié)的 【簡(jiǎn)單黑名單模式】 有一個(gè)非常大的弊端,就是每個(gè) Token 驗(yàn)證時(shí)都需要去驗(yàn)證是否在黑名單,正常情況下,我們正常的Token 是占絕大多數(shù)的,如果用此種機(jī)制,那么對(duì)資源是一種很大的浪費(fèi)。那么我們需要設(shè)立一種機(jī)制,來(lái)讓我們認(rèn)為?可疑?的Token進(jìn)行黑名單驗(yàn)證,那么如何來(lái)判斷Token是否可疑呢,我這里想了一種方式。
如何判斷 Token 是否可疑:
我們?cè)谏蒚oken的時(shí)候,可以添加自定義 Claim (身份信息單元),那么我們可以參考網(wǎng)站登錄的安全機(jī)制,那么我們可以添加一個(gè)用戶ip的Claim,這樣我們生成的Token都會(huì)攜帶用戶生成Token時(shí)的IP,我們每次驗(yàn)證Token是否有效時(shí),就可以根據(jù)客戶端來(lái)源IP與Token攜帶的IP進(jìn)行匹配,如果匹配不上,那么該Token我們就可以認(rèn)為是可疑的,從而進(jìn)行黑名單的驗(yàn)證。
該方式相對(duì)于前面的 【簡(jiǎn)單黑名單模式】模式算是一個(gè)比較好的進(jìn)階了。
在這里,我們還需要考慮到IP作為用戶的私密信息,我們將IP放入Token時(shí),需要對(duì)IP進(jìn)行加密。因?yàn)?JWT Token 前兩部分,僅僅是 base64 Encode 而已。
Claim 詳解請(qǐng)參考?http://www.cnblogs.com/stulzq/p/8726002.html
3.強(qiáng)化黑名單模式
無(wú)論是【簡(jiǎn)單黑名單模式】還是【進(jìn)階黑名單模式】,我們?cè)趯?duì)比黑名單時(shí)是對(duì)token進(jìn)行完全比對(duì),這樣的方式,在某些場(chǎng)景就存在局限性,比我想讓該用戶在某某時(shí)間以前頒發(fā)的Token都算作黑名單。所以我們?cè)谂袛嗪诿麊螘r(shí)可以根據(jù)用戶id以及token頒發(fā)時(shí)間來(lái)判斷。如果讓規(guī)則自動(dòng)失效?我們可以用前面設(shè)定的 token頒發(fā)時(shí)間加上我們頒發(fā)服務(wù)設(shè)置的token有效時(shí)間就等于規(guī)則失效時(shí)間。
4.將Token添加進(jìn)黑名單的方式
我們前面設(shè)立了黑名單模式,那么我們的Token何時(shí)加入黑名單呢,難道讓用戶說(shuō),我的 Token 被盜了,你把我的 Token加入黑名單吧,這肯定不現(xiàn)實(shí)。我們可以在退出登錄時(shí),就自動(dòng)往黑名單添加一條規(guī)則,采用【強(qiáng)化黑名單模式】添加用戶id以及當(dāng)前時(shí)間作為token頒發(fā)時(shí)間來(lái)驗(yàn)證。比如用戶id1000,此用戶在 2018-09-20 12:11 退出,我們就可以添加一條規(guī)則?userid=1000,tokenissuetime=2018-09-20 12:11?,該規(guī)則表示只要用戶id為1000的并且token頒發(fā)時(shí)間小于2018-09-20 12:11的token,都被算作黑名單token。
這時(shí)有人可能會(huì)說(shuō),這個(gè)token如果還是這個(gè)用戶再次拿來(lái)使用,那還是有效的,你這個(gè)怎么沒(méi)讓他失效呢?我們?cè)O(shè)立黑名單模式就是為了避免用戶的還在有效期的Token被他人惡意使用。對(duì)于用戶自己來(lái)說(shuō),這個(gè)問(wèn)題就無(wú)關(guān)緊要了。
5.全部 Token 失效的機(jī)制。
全部Token失效的方式,目前我想了兩種:
1.更換頒發(fā)服務(wù)的密鑰對(duì),并且重啟所有資源服務(wù)(資源服務(wù)獲取的公鑰默認(rèn)存在內(nèi)存,重啟可以丟失)。這樣原本的Token在驗(yàn)證時(shí),將會(huì)找不到對(duì)應(yīng)的公鑰,導(dǎo)致驗(yàn)簽失敗從而Token無(wú)效。
2.類(lèi)似于前面【強(qiáng)化黑名單模式】的驗(yàn)證黑名單的方式,我們可以在驗(yàn)證Token的流程中加兩個(gè)配置,一個(gè)是控制這種配置是否開(kāi)啟的開(kāi)關(guān),一個(gè)是某個(gè)時(shí)間,規(guī)則就是如果在這個(gè)時(shí)間以前頒發(fā)Token全部算作無(wú)效Token。這種就需要資源服務(wù)支持熱加載配置,從而避免重啟資源服務(wù)。
我個(gè)人推薦第二種方式。
四.其他解決方案
這里的內(nèi)容是根據(jù)評(píng)論整理的,我個(gè)人的想法不可能面面俱到,所以整理了一下評(píng)論里比較不錯(cuò)的方案:
Savorboard:
JWT 的最佳實(shí)踐是遵循默認(rèn)的過(guò)期策略(15分鐘過(guò)期), 他能夠有效的保證Token的有效性。 刷新Token是為了保證身份驗(yàn)證的服務(wù)端與授予令牌的客戶端在訪問(wèn)權(quán)限方面保持一致,比如Claim里可能包含最新的訪問(wèn)權(quán)限,這是一個(gè)必要且必須的過(guò)程。
所以,頻繁的15分鐘刷新令牌是有必要的,這并不足以對(duì)服務(wù)器的性能產(chǎn)生很大的影響。
五.寫(xiě)在最后
文中所訴是總結(jié)了我長(zhǎng)久以來(lái)的想法,token加入ip還有根據(jù)id和頒發(fā)時(shí)間驗(yàn)證黑名單都是我今天無(wú)意間想到的。如果你閱讀了本文有什么不明白或者你認(rèn)為有改進(jìn)的地方,或者更好的地方,歡迎在評(píng)論與我交流。本文的問(wèn)題,有很多人問(wèn)過(guò)我,也討論了不少,我相信很多人在使用ids4是可能會(huì)有這樣的問(wèn)題,所以在此發(fā)表了我的一個(gè)觀點(diǎn),希望能給你參考,后續(xù)的文章我會(huì)根據(jù)這個(gè)想法來(lái)實(shí)現(xiàn)。
原文地址:https://www.cnblogs.com/stulzq/p/9678501.html
.NET社區(qū)新聞,深度好文,歡迎訪問(wèn)公眾號(hào)文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的IdentityServer4实战 - 谈谈 JWT Token 的安全策略的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: asp.net core webapi项
- 下一篇: 使用.Net Core实现FNV分布式h