.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析
介紹JwtToken認(rèn)證之前,必須要掌握.Net Core認(rèn)證系統(tǒng)的核心原理,如果你還不了解,請(qǐng)參考.Net Core 認(rèn)證組件源碼解析,且必須對(duì)jwt有基本的了解,如果不知道,請(qǐng)百度.最重要的是你還需要掌握identity server4的基本用法,關(guān)于identity server4因?yàn)樯婕暗絻蓚€(gè)協(xié)議Oath2.0和openid connect協(xié)議,內(nèi)容較多,不是本文重點(diǎn),后續(xù)有時(shí)間我會(huì)寫一片關(guān)于identity server4的源碼分析.且為了保證整個(gè)系統(tǒng)的高度可控,我重寫了整個(gè)id4,留下了password模式.如果有興趣,可以關(guān)注本人的后續(xù)文章.
假設(shè)你已經(jīng)掌握以上內(nèi)容,那么整個(gè)流程可以抽象為如下步驟:
(1)、用戶輸入用戶名密碼同時(shí)帶著客戶端Id和客戶端密鑰去identity server4請(qǐng)求access token.(訪問(wèn)令牌,令牌中帶著用戶Id,帶著客戶端的名稱和密碼)
(2)、拿到token后,接著用戶去請(qǐng)求客戶端指定的控制器方法,那么客戶端第一步,會(huì)解析token中的客戶端名稱和密碼是否正確,還有過(guò)期時(shí)間等常規(guī)字段的判斷.
(3)、token驗(yàn)證通過(guò),這個(gè)時(shí)候就可以拿到用戶信息(ClaimsPrincipal)
(4)、此時(shí)我們拿到持有的用戶信息中的用戶Id,發(fā)起httpclient或者grpc調(diào)用,去統(tǒng)一權(quán)限系統(tǒng)查找用戶的權(quán)限是否有當(dāng)前請(qǐng)求的方法,有就通過(guò)授權(quán)認(rèn)證,返回?cái)?shù)據(jù),沒(méi)有,就返回權(quán)限不足.
?
整個(gè)流程大致如上,本文的重點(diǎn)是當(dāng)拿到id4頒發(fā)的有效令牌(token)后,客戶端如何解析?
IdentityServer4 提供了IdentityServer4.AccessTokenValidation類庫(kù),用來(lái)解析id4頒發(fā)的token.
.Net Core啟用IdentityServer4token驗(yàn)證的方法如下:
?
指定id4的認(rèn)證方案,并指定認(rèn)證參數(shù),那么看看里面到底干了什么
?因?yàn)閕d4的令牌有訪問(wèn)令牌和引用令牌之分,但是password模式,只支持訪問(wèn)令牌,所以
?
?這兩塊這里就不分析了,如果你的項(xiàng)目用到了引用令牌.那么自行查閱代碼.
ok,回到第一行代碼
?很明顯添加了JwtBearer的認(rèn)證方案.所以IdentityServer4.AccessTokenValidation類庫(kù)是基于
回到.Net Core JwtBear認(rèn)證的源碼如下:
?很簡(jiǎn)單,添加了方案名稱為Bearer?IdentityServerAuthenticationJwt的認(rèn)證方案,且處理器為JwtBearerHandler,并指定參數(shù).如果你已經(jīng)掌握.Net Core的核心認(rèn)證組件的流程,那么啥都不用說(shuō),直接看JwtBearerHandler干了什么,查看核心的認(rèn)證方法HandleAuthenticateAsync,源碼如下:
?第一步,生成上下文,執(zhí)行通過(guò)JwtBearerOptions參數(shù)注冊(cè)的MessageReceived事件,源碼如下:
?所以,在token認(rèn)證前,可以隨意操作上下文,微軟提示,給當(dāng)前應(yīng)用一個(gè)機(jī)會(huì)去拒絕一部分token。當(dāng)然很明顯,你可以干除了拒絕之外的很多事情.
接著
?檢查http head頭中的token是否合法,條件代碼中也給出了.必須以Bearer開頭等
接下來(lái),這段代碼就很有趣了,如果你不了解identity Server4,你肯定無(wú)法下手.
?核心對(duì)象
?這個(gè)對(duì)象在IdentityModel類庫(kù)中有,但是這里不介紹了
協(xié)議層面的東東,所以可以自行查詢?cè)创a.
接著回到JwtBearer認(rèn)證的入口
?為啥要注入JwtBearerPostConfigureOptions這個(gè)配置對(duì)象呢?且這個(gè)配置對(duì)象是干嘛的呢?關(guān)于PostConfigureOpetions是.Net Core核心配置系統(tǒng)里面的一類對(duì)象,這類對(duì)象會(huì)在Options執(zhí)行完畢之后執(zhí)行,類似ABP模塊加載系統(tǒng)的生命周期管理,執(zhí)行完Init之后執(zhí)行Post里面的方法,這里本質(zhì)也是如此.ok,看看這個(gè)配置干了什么,源碼如下:
?
?到這里一目了然.ConfigurationManager實(shí)際就是去遠(yuǎn)程調(diào)用文檔配置(本質(zhì)是去拿給token前面的rsa文件,來(lái)給token解密,并驗(yàn)證token的有效性)用的.
?調(diào)用的是id4的文檔配置,但是我為了減少不必要的遠(yuǎn)程調(diào)用,拿掉了id4的文檔發(fā)現(xiàn)TokenPoint.改用在客戶端直接配置ras文件,來(lái)給token解密,這里因?yàn)槲矣玫氖莗assword模式,所有的系統(tǒng)都是高度信任的.所以可以這樣做.而且微軟也考慮到了這一點(diǎn),代碼如下:
?你可以跳過(guò)遠(yuǎn)程調(diào)用,而改用本地直接配置.參數(shù)在JwtBearerOptions的TokenValidationParameters屬性中配置.
這個(gè)時(shí)候你已經(jīng)通過(guò)本地配置,或者通過(guò)調(diào)用id4的文檔發(fā)現(xiàn)TokenPoint拿到了給token簽名的rsa文件,接著
?
?
?調(diào)用JwtBearerOptions配置參數(shù)中的SecurityTokenValidators,源碼如下:
?本質(zhì)就是調(diào)用JwtSecurityTokenHandler去驗(yàn)證token的內(nèi)容是否有效,并解析出用戶信息,源碼如下:
?并返回認(rèn)證結(jié)果.
所以整個(gè)核心認(rèn)證流程如下:
1、拿到http請(qǐng)求上下文中的token
2、執(zhí)行一系列事件
3、遠(yuǎn)程調(diào)用id4文檔發(fā)現(xiàn)服務(wù)拿到簽名rsa文件或者本地指定rsa文件
4、用私鑰解密token,判斷其有效性
5、執(zhí)行一系列事件
6、返回用戶認(rèn)證結(jié)果
整個(gè)核心的流程可以抽象出如下代碼:
?此時(shí)就拿到可以訪問(wèn)的token,里面包含用戶Id的信息,接著配合授權(quán)系統(tǒng)的動(dòng)態(tài)授權(quán)功能,去權(quán)限系統(tǒng)判斷當(dāng)前用戶是否具有訪問(wèn)當(dāng)前Api的權(quán)限.就能判斷當(dāng)前請(qǐng)求是否被允許
這里只介紹了id4 token的核心認(rèn)證流程,一些細(xì)節(jié)點(diǎn),比如token的有效性校驗(yàn),就有很多內(nèi)容沒(méi)介紹.不明白,可以在下面提問(wèn).
?
注意:如果你和我一樣重寫了id4,同時(shí)你拿掉了文檔發(fā)現(xiàn)tokenPoint,那么就不能用IdentityServer4.AccessTokenValidation組件了(我暫時(shí)沒(méi)找到,我覺(jué)得也沒(méi)必要,直接自己寫了),只能使用JwtBear認(rèn)證組件,再參考
IdentityServer4.AccessTokenValidation組件中的IdentityServerAuthenticationOptions參數(shù)中的ConfigureJwtBearer方法指定JwtBear必須的認(rèn)證參數(shù),來(lái)實(shí)現(xiàn)自定義的Id4token驗(yàn)證.
純屬個(gè)人理解,能力有限,有問(wèn)題,請(qǐng)指正,謝謝
總結(jié)
以上是生活随笔為你收集整理的.Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ProjectFileManager 发
- 下一篇: abp vnext2.0之核心组件模块加