介紹JwtToken認證以前,必需要掌握.Net Core認證系統的核心原理,若是你還不瞭解,請參考.Net Core 認證組件源碼解析,且必須對jwt有基本的瞭解,若是不知道,請百度.最重要的是你還須要掌握identity server4的基本用法,關於identity server4由於設計到兩個協議Oath2.0和openid connect協議,內容較多,不是本文重點,後續有時間我會寫一片關於identity server4的源碼分析.且爲了保證整個系統的高度可控,我重寫了整個id4,留下了password模式.若是有興趣,能夠關注本人的後續文章.html
假設你已經掌握以上內容,那麼整個流程能夠抽象爲以下步驟:ide
(1)、用戶輸入用戶名密碼同時帶着客戶端Id和客戶端密鑰去identity server4請求access token.(訪問令牌,令牌中帶着用戶Id,帶着客戶端的名稱和密碼)源碼分析
(2)、拿到token後,接着用戶去請求客戶端指定的控制器方法,那麼客戶端第一步,會解析token中的客戶端名稱和密碼是否正確,還有過時時間等常規字段的判斷.post
(3)、token驗證經過,這個時候就能夠拿到用戶信息(ClaimsPrincipal)url
(4)、此時咱們拿到持有的用戶信息中的用戶Id,發起httpclient或者grpc調用,去統一權限系統查找用戶的權限是否有當前請求的方法,有就經過受權認證,返回數據,沒有,就返回權限不足.設計
整個流程大體如上,本文的重點是當拿到id4頒發的有效令牌(token)後,客戶端如何解析?3d
微軟提供了IdentityServer4.AccessTokenValidation類庫,用來解析id4頒發的token.server
.Net Core啓用IdentityServer4token驗證的方法以下:jwt
指定id4的認證方案,並指定認證參數,那麼看看裏面到底幹了什麼htm
由於id4的令牌有訪問令牌和引用令牌之分,可是password模式,只支持訪問令牌,因此
這兩塊這裏就不分析了,若是你的項目用到了引用令牌.那麼自行查閱代碼.
ok,回到第一行代碼
很明顯添加了JwtBearer的認證方案.因此IdentityServer4.AccessTokenValidation類庫是基於
回到.Net Core JwtBear認證的源碼以下:
很簡單,添加了方案名稱爲Bearer IdentityServerAuthenticationJwt的認證方案,且處理器爲JwtBearerHandler,並指定參數.若是你已經掌握.Net Core的核心認證組件的流程,那麼啥都不用說,直接看JwtBearerHandler幹了什麼,查看核心的認證方法HandleAuthenticateAsync,源碼以下:
第一步,生成上下文,執行經過JwtBearerOptions參數註冊的MessageReceived事件,源碼以下:
因此,在token認證前,能夠隨意操做上下文,微軟提示,給當前應用一個機會去拒絕一部分token。固然很明顯,你能夠幹除了拒絕以外的不少事情.
接着
檢查http head頭中的token是否合法,條件代碼中也給出了.必須以Bearer開頭等
接下來,這段代碼就頗有趣了,若是你不瞭解identity Server4,你確定沒法下手.
核心對象
這個對象在IdentityModel類庫中有,可是這裏不介紹了
協議層面的東東,因此能夠自行查詢源碼.
接着回到JwtBearer認證的入口
爲啥要注入JwtBearerPostConfigureOptions這個配置對象呢?且這個配置對象是幹嗎的呢?關於PostConfigureOpetions是.Net Core核心配置系統裏面的一類對象,這類對象會在Options執行完畢以後執行,相似ABP模塊加載系統的生命週期管理,執行完Init以後執行Post裏面的方法,這裏本質也是如此.ok,看看這個配置幹了什麼,源碼以下:
到這裏一目瞭然.ConfigurationManager實際就是去遠程調用文檔配置(本質是去拿給token前面的rsa文件,來給token解密,並驗證token的有效性)用的.
調用的是id4的文檔配置,可是我爲了減小沒必要要的遠程調用,拿掉了id4的文檔發現TokenPoint.改用在客戶端直接配置ras文件,來給token解密,這裏由於我用的是password模式,全部的系統都是高度信任的.因此能夠這樣作.並且微軟也考慮到了這一點,代碼以下:
你能夠跳過遠程調用,而改用本地直接配置.參數在JwtBearerOptions的TokenValidationParameters屬性中配置.
這個時候你已經經過本地配置,或者經過調用id4的文檔發現TokenPoint拿到了給token簽名的rsa文件,接着
調用JwtBearerOptions配置參數中的SecurityTokenValidators,源碼以下:
本質就是調用JwtSecurityTokenHandler去驗證token的內容是否有效,並解析出用戶信息,源碼以下:
並返回認證結果.
因此整個核心認證流程以下:
一、拿到http請求上下文中的token
二、執行一系列事件
三、遠程調用id4文檔發現服務拿到簽名rsa文件或者本地指定rsa文件
四、用私鑰解密token,判斷其有效性
五、執行一系列事件
六、返回用戶認證結果
整個核心的流程能夠抽象出以下代碼:
此時就拿到能夠訪問的token,裏面包含用戶Id的信息,接着配合受權系統的動態受權功能,去權限系統判斷當前用戶是否具備訪問當前Api的權限.就能判斷當前請求是否被容許
這裏只介紹了id4 token的核心認證流程,一些細節點,好比token的有效性校驗,就有不少內容沒介紹.不明白,能夠在下面提問.
注意:若是你和我同樣重寫了id4,同時你拿掉了文檔發現tokenPoint,那麼就不能用IdentityServer4.AccessTokenValidation組件了(我暫時沒找到,我以爲也不必,直接本身寫了),只能使用JwtBear認證組件,再參考
IdentityServer4.AccessTokenValidation組件中的IdentityServerAuthenticationOptions參數中的ConfigureJwtBearer方法指定JwtBear必須的認證參數,來實現自定以的Id4token驗證.
純屬我的理解,能力有限,有問題,請指正,謝謝