【.NET Core專案實戰-統一認證平臺】第十章 授權篇-客戶端授權
上篇文章介紹瞭如何使用
Dapper
持久化IdentityServer4(以下簡稱ids4)
的資訊,並實現了sqlserver
和mysql
兩種方式儲存,本篇將介紹如何使用ids4
進行客戶端授權。.netcore專案實戰交流群(637326624),有興趣的朋友可以在群裡交流討論。
一、如何新增客戶端授權?
在瞭解如何進行客戶端授權時,我們需要了解詳細的授權流程,在【.NET Core專案實戰-統一認證平臺】第八章 授權篇-IdentityServer4原始碼分析一篇中我大概介紹了客戶端的授權方式,本篇再次回憶下客戶端的授權方式,老規則,上原始碼。
首先檢視獲取token的方式,核心程式碼如下。
我們需要詳細分析下第一步客戶端授權資訊是如何驗證的?核心程式碼如下。
這裡幾個方法可以從寫的說明備註裡就可以知道什麼意思,但是 var parsedSecret = await _parser.ParseAsync(context);
這句話可能不少人有疑問,這段是做什麼的?如何實現不同的授權方式?
這塊就需要繼續理解Ids4
的實現思路,詳細程式碼如下。
就是從注入的預設實現裡檢測任何一個實現ISecretParser
介面方法,通過轉到實現,可以發現有PostBodySecretParser、JwtBearerClientAssertionSecretParser、BasicAuthenticationSecretParser
Ids4
時支援哪幾種客戶端授權方式。從上面程式碼可以發現,預設注入了兩種分析器,我們就可以通過這兩個方式來做客戶端的授權,下面會分別演示兩種授權方式的實現。
BasicAuthenticationSecretParser
由於程式碼比較簡單,就不介紹了,這裡直接模擬此種方式授權,開啟
PostMan
,在Headers中增加Authorization的Key,並設定Value為Basic YXBwY2xpZW50JTNBc2VjcmV0
,其中Basic後為client_id:client_secret
PostBodySecretParser
此種認證方式就是從
form_data
提取client_id
和client_secret
資訊,我們使用PostMan
繼續模擬客戶端授權,測試結果如下,也可以得到我們想要的結果。
有了前面的兩個授權方式,我們清楚了首先驗證客戶端的授權資訊是否一致,再繼續觀察後續的執行流程,這時會發現TokenRequestValidator
中列出了客戶端授權的其他資訊驗證,詳細定義程式碼如下。
詳細的授權驗證程式碼如下,校驗客戶端授權的一般規則。
最終輸出詳細的校驗結果資料,現在整個客戶端授權的完整邏輯已經介紹完畢,那如何新增我們的自定義客戶端授權呢?比如我要給客戶端A開放一個訪問介面訪問許可權,下面就開通客戶端A為案例講解。
開通客戶端授權
根據前面介紹的驗證流程,我們清楚首先需要增加客戶端資訊,這裡起名叫clienta
,密碼設定成secreta
。上一篇我們介紹了Dapper
持久化IdentityServer4
的授權資訊,所以這裡我就直接以SQL語句的方式來演示新增配置資訊。詳細的語句如下:
然後我們來測試下新開通的客戶端授權,如下圖所示,可以正常獲取授權資訊了,另外一種Basic授權方式可自行測試。
二、如何配合閘道器認證和授權?
前面使用的是專案自己進行驗證的,正式專案執行時,我們會把請求放到閘道器中,統一由閘道器進行認證和授權等操作,內部api無需再次進行認證和授權,那如何實現閘道器認證和授權呢?
我們可以回憶下之前介紹閘道器篇時認證篇章,裡面介紹的非常清楚。這裡我們參照剛才新增的客戶端A為案例增加閘道器授權,因為我們對外暴露的是閘道器地址,而不是內部具體認證專案地址。
1、新增閘道器授權路由
本專案的閘道器埠為7777,所以閘道器授權的地址為http://localhost:7777/connect/token
,由於為新增閘道器路由,直接訪問報401,我們首先增加閘道器的路由資訊。
通過PostMan
測試,可以得到我們預期的授權資訊結果。
然後繼續訪問我們之前配置的授權路由,提示401未授權,這塊就涉及到前面閘道器篇的知識了,因為我們的閘道器增加了授權,所以需要增加客戶端授權才能訪問。
2、新增客戶端授權訪問
還記得是如何新增客戶端授權的嗎?詳細介紹參考[【.NET Core專案實戰-統一認證平臺】第六章 閘道器篇-自定義客戶端授權 ,我直接把授權的指令碼編寫如下:
--7、插入把客戶端加入測試路由組2INSERT INTO AhphClientGroup VALUES(21,2)
使用我們剛授權的資訊,再次訪問之前配置的需要認證的路由,可以得到我們預期的結果,奈斯,和閘道器篇的內容完全一致。
注意:在配置完資訊後需要清理快取,因為我們之前做閘道器時,很多配置資訊的讀取使用了快取。
三、如何統一輸出結果?
作為一塊準備應用到生產環境的產品,可能為各種第三方提供應用支援,那麼統一的輸出結果是必須要實現的,比如我們使用微信sdk或其他第三方sdk時,會發現它們都會列出出現錯誤的統一提示,由標識程式碼和說明組成,這裡我們就需要解決如何標準化輸出問題,自己業務系統輸出標準結果很容易,因為都是自己控制的結果輸出,那麼我們閘道器整合Ocelot
、認證整合IdentityServer4
,這兩塊如何進行標準化輸出呢?
那開始我們的改造之旅吧,首先我們要明確如果遇到錯誤如何進行輸出,我們定義一個輸出基類BaseResult
,詳細的定義如下:
1、閘道器預設輸出改造
閘道器這段需要改造錯誤提示的程式碼和內容以及異常的輸出結果,首先改造錯誤情況的輸出結果,使用BaseResult
統一輸出,這裡就需要重寫輸出中介軟體ResponderMiddleware
,下面就開始重寫之旅吧。
新增自定義輸出中介軟體CzarResponderMiddleware
,詳細程式碼如下:
然後新增中介軟體擴充套件,程式碼如下。
最後使用此擴充套件來接管預設的輸出中介軟體,詳細程式碼如下。
//builder.UseResponderMiddleware();builder.UseCzarResponderMiddleware();
好了,閘道器統一輸出中介軟體就完成了,是不是很簡單呢?我們來測試下效果吧,PostMan
閃亮登場,
奈斯,這才是我們需要的結果,那如何異常會輸出什麼呢??我們來模擬下結果,我直接在服務端丟擲異常測試。
預設情況會支援輸出異常的堆疊資訊。那如何捕獲服務端異常資訊呢?我們需要了解在哪裡傳送了後端請求,通過原始碼分析,發現是由HttpRequesterMiddleware
中介軟體做後端請求,這時我們只需要改造下此中介軟體即可完成統一異常捕獲。改造核心程式碼如下:
修改測試後端服務程式碼如下,
然後通過閘道器訪問路由地址http://localhost:7777/ctr/values/1
,輸出為{"errcode":500,"errmsg":"請求服務異常"}
,得到了預期的所有目標,閘道器統一輸出全部改造完畢。
2、認證的統一輸出改造
這裡為了統一風格,我們先檢視下Ids4
的錯誤提示方式和輸出結果,然後配合原始碼可以發現到輸出都是繼承IEndpointResult
介面,並定義了各種方式的輸出,且校驗失敗時,輸出的狀態碼都不是200,那麼我們可以從這裡下手,在閘道器層增加獨立的判斷,來相容自定義的輸出。改造程式碼如下:
改造完成後,我們隨時請求認證記錄,最終顯示效果如下。
奈斯,輸出風格統一啦,這樣就完美的解決了兩個元件的輸出問題,終於可以開心的使用啦。
四、內容總結
本篇我們詳細的介紹了客戶端授權的原理和支援的兩個授權的方式,並各自演示了呼叫方式,然後知道了如何在資料庫端新開通一個客戶端的資訊,然後介紹了配合閘道器實現客戶端的授權和認證,並再次介紹了閘道器端的路由配置情況,最後介紹瞭如何把閘道器和認證統一輸出格式,便於我們在正式環境的使用,涉及內容比較多,如果中間實現的有不對的地方,也歡迎大家批評指正。
相關文章:
原文地址:https://www.cnblogs.com/jackcao/p/10100621.html
.NET社群新聞,深度好文,歡迎訪問公眾號文章彙總 http://www.csharpkit.com