目錄
- 專案核心內容
- 實戰目標
- RGCA 四步架構法
專案核心內容
- 無程式碼埋點實現對所有 API Action 訪問控制管理
- 對 EF Core 實體新增、刪除、欄位級讀寫控制管理
- 與 Identity 進行融合整合
實戰目標
- RGCA 四步架構法的應用
- 加深對 OPM 和 OPD 的運用
- 為畢業設計打下基礎
RGCA 四步架構法
- Requirement:從利益相關者獲取需求
- Goal:將需求轉化為目標(功能意圖)
- Concept:將目標擴充套件為完整概念
- Architecture:將概念擴充套件為架構
從利益相關者獲取需求
- 受益原則
- 痛點
- 利益相關者
- 需求分類、排序、特徵
受益原則
好的架構必須使人受益,要想把架構做好,就要專注於功能的湧現,使得系統把它的主要功能通過跨越系統邊界的介面對外展示出來
痛點
對於企業內部的管理系統而言基本上都會有一個許可權管理系統,產品經理在進行產品設計的時候需要先確定每一個選單,每一個按鈕的 key 是什麼,再將 key 與許可權進行匹配、繫結
但是產品經理無法確定未來所有需要許可權管理的地方,所以需要開發人員提前為所有地方設定 key
由於需要設定的 key 有很多,所以可能命名不規範,也有可能會有缺漏,未來涉及到遺漏的地方就需要開發人員重新編碼、釋出才能滿足需求,這是開發企業內部許可權管理功能的痛點
利益相關者
- 甲方:開發人員,架構師,投資人
- 客戶方:開發人員,產品經理,系統運營人員,老闆
受益人 | 需求 |
---|---|
開發者 | 1、整合簡單,少寫程式碼;2、功能靈活,可以擴充套件;3、不要綁死,可以插拔;4、低程式碼侵入性,不影響業務程式碼 |
產品經理 | 1、隨時可以增加對系統裡面功能和資料的許可權控制 |
系統管理員 | 1、希望能靈活對系統的許可權進行配置,適合角色與員工結構,依照通用行業標準進行配置 |
開發者所屬公司 | 1、低成本(划算);2、不要綁死 |
投資人 | 1、通過該專案的完整演示 RGCA 的架構設計過程;2、將此係統開源回饋到社群,以獲得更多開發者的支援;3、進一步蒐集開發者和企業使用者的需求以進行下一步的開發 |
需求分類、排序、特徵
提出人 | 分類 | 需求 | 優先順序 | 分類 | KANO |
---|---|---|---|---|---|
產品經理 | - | 隨時可以增加對於系統裡面功能和資料的許可權控制,不需要開發和釋出系統 | - | 總體的意願 | 基本型 |
產品經理 | 許可權管理 | 可以對功能和頁面進行組合成一個許可權給角色,一次配置即可 | 一期 | 必需品 | 基本型 |
產品經理 | 資料許可權 | 資料可以控制到新增、刪除、欄位級別的修改 | 一期 | 必需品 | 基本型 |
產品經理 | 資料許可權 | 可以根據不同的角色、部門、進行查詢資料欄位的控制 | 推遲 | 必需品 | 反向型 |
產品經理 | 資料許可權 | 可以控制不同的部門、角色檢視的資料(比如只能看我所在部門的資料) | 推遲 | 必需品 | 基本型 |
系統管理員 | 許可權管理 | 配置方便(使用一定的行業標準進行設計) | - | 必需品 | 無差異型 |
系統管理員 | 功能許可權 | 可以對系統內的所有頁面訪問進行許可權控制 | 推遲 | 必需品 | 基本型 |
系統管理員 | 功能許可權 | 可以對系統內的所有頁面的按鈕進行許可權控制 | 推遲 | - | - |
系統管理員 | 功能許可權 | 對後臺所有API請求進行許可權控制 | 一期 | - | - |
開發人員 | 整合 | 整合簡單,少寫程式碼 | - | 對缺失物品所表現出來的慾望 | 期望型 |
開發人員 | 整合 | 功能靈活,可擴充套件 | - | 對缺失物品所表現出來的慾望 | 期望型 |
開發人員 | 整合 | 可插拔 | - | 必需品 | - |
開發人員 | 整合 | 低程式碼侵入性,不影響業務程式碼 | - | 必需品 | - |
客戶公司高層 | - | 低成本 | - | 總體意願 | - |
客戶公司高層 | - | 可插拔 | - | 對缺失物品所表現出來的慾望 | - |
投資公司 | - | 低成本投入、快速可驗證(敏捷,精益),少走彎路 | - | 總體的意願 | - |
投資公司 | - | 通過該專案的完整演示 RGCA 的架構設計過程(時間為兩天) | - | 必需品 | - |
投資公司 | - | 將此係統開源回饋到社群,以獲得更多開發者的支援 | - | 對缺失物品所表現出來的慾望 | - |
投資公司 | - | 能夠在企業生產系統中使用 | - | 必需品 | - |
將需求轉化為目標(功能意圖)
從系統的頂層角度:定義系統的形式和功能
確定功能意圖(功能意圖是由主要受益者,主要需求而推匯出來的)
形式:通用的許可權管理系統
to..by..using
為了...通過...使用
功能:無需程式碼埋點,通過UI配置改變資源(頁面、按鈕、資料、API)的可訪問性,達到許可權控制的目的
過程 + 操作 <= 工具
受益者 | 系統管理員 & 產品經理 |
---|---|
需求? | 對系統中受保護的資源進行許可權保護 |
與解決方案無關的操作物件 | 受保護的資源 |
與利益相關的屬性 | 可訪問性,完整性 |
運算元的其他屬性 | 可配置性,可訪問性 |
與解決方案無關的過程 | 攔截/保護 |
無關過程的屬性 | 準確性 |
將目標擴充套件為完整概念
在目標階段提出了與解決方案無關的過程:攔截,一個模糊抽象的過程,沒有說明由誰來攔截,以什麼方式來攔截
與解決方案無關的操作物件:受保護的資源,一個抽象的物件,由需求匯出了物件的分類,但是仍然沒有特別具體,沒有具體的場景
到了概念階段需要提出具體解決方案過程:從解決方案不相關,到與解決方案相關
解決方案是幫助我們解決問題的,在目標階段大致定義了需要解決什麼問題,功能層面只是說明了產品的優勢
具體的解決方案是在概念階段提出的,它體現出如何把功能進行詳細的描述,所以需要推導到到與解決方案相關的場面
受保護的資源以 API 為例進行推導,定義為 API Action,而攔截在 ASP .NET Core 中表現為 AuthorizationFilter
因為它是一個名詞,不能代表一個過程,所以加上 ing 代表一個過程 AuthorizationFiltering
API Action 經過 AuthorizationFiltering 之後變成一個與解決方案相關的東西
在 ASP .NET Core Mvc 裡面變成一個 Result,它是 AuthorizationContext 的一個屬性
Result 有幾種型別:Sucess,Forbiden,Challenge
受保護的資源除了 API Action 之外,還可以是 Entity,而所有 EF 的操作最終都放在 DBContext
DBContext 有一個 SaveChanges 的操作,以及一個 ChangeTracker 的屬性記錄了實體的所有狀態
特化:變得更具體
從受保護的資源到 API Action 就是一個特化的過程,從目標到概念也是一個特化的過程
泛化:變得更抽象
從資料、頁面、按鈕、API 到受保護的資源就是一個泛化的過程
攔截的意圖:保護資源
AuthorizationFilter 在 ASP .NET Core 中只能通過在 Action 上面打標籤 Authorize 的方式進行攔截
這就是所謂的程式碼埋點,比如在 entity 上面打標籤也是程式碼埋點
攔截的上一層是保護資源,攔截是保護資源的一種方式,需要提前定義受保護的資源
除了受保護的資源,對於所有資源需要動態保護,可以通過動態攔截的方式
動態攔截需要實現一個 DynamicAuthorizationFiltering,不能覆蓋原有的功能
保護資源的上一層是安全,安全除了保護資源,還有很多其他的事情可以做,比如記錄日誌
審計日誌會記錄使用者的所有訪問記錄,企業可以設定許可權
通過這種方式可以不停地將需求往上一層尋找,一直達到最頂層
除了向上之外還可以向下尋找,延伸出整體概念,通過概念片段的組合,構成完整的整體概念
接下來對攔截這一過程進行展開,展開為一組必須得到執行的內部過程,針對每一個內部過程,選用特定的運算元、過程及工具物件對其進行特化,就可以得到相應的概念片段,這也是一個特化的過程
- 配置:系統管理員希望對後臺所有 API 請求進行許可權控制,所以首先需要知道有哪些 API,對每一個 action 需要可以配置
- 賦權:把角色賦權給使用者
- 認證:使用者認證之後有一個身份
- 授權:基於身份可以進行授權
將概念擴充套件為架構
- 價值通路與系統架構
- 層級分解
價值通路與系統架構
從資源變成許可權,許可權繫結給使用者,使用者進行登入,登入之後再進行授權
資源分為 ActionAccess 和 EntityAccess
EntityAccess 有 CanCreate,CanDelete,EntityName,Key 幾個屬性,以及每個欄位是否允許修改 MemberAccess
同理 ActionAccess 有 Url,Name,DisplayName,Verb 幾個屬性
註冊資源分為 Entity Explorer 和 API Explorer
Entity Explorer 通過 DbContext 進行掃描獲取需要監聽的實體進行註冊
API Explorer 通過 IActionDescriptorCollectionProvider 註冊 Action
授權有一個攔截器 AuthorizeFilter
ASP .NET Core Identity 有一個基於 Claims 的認證授權機制,它是一個 key:value 的陣列
Clamis 屬於 User 物件,User 物件屬於 HttpContext
AuthorizeFilter 接收 Claims 和 ActionDescriptior,在 Claims 裡面可以獲取到 Action 的資訊,所以兩者有關聯關係
對於賦權這一步需要定義許可權 Permission 和角色,將許可權和角色輸入到賦權,產生一個角色許可權 RolePermission
角色許可權 RolePermission 是一個組合物件,包含角色與許可權
許可權和資源之間有一個包含關係,一個許可權包含多個資源
至此完成了一條通路:給多個 Action 定義 key 之後,將 key 賦值給角色,角色繫結到使用者,使用者登入的時候可以獲取到一個 Action 的列表,通過 AuthorizeFilter 來進行對比
授權由 AuthorizationContext 判斷是否有許可權
響應分為 API 響應 和 Entity 響應,針對不同的響應有不同的處理方式
對於 API 響應需要判斷是否允許有許可權,未認證返回401,無許可權返回403
對於 Entity 響應需要 Claims 和 EntityAccessList,通過 Claim 和 AccessList 進行對比
使用者登入之後得到 User 身份,發起請求產生 ActionRequest
ActionRequest 屬於 HttpContext,最後會輸入到 AuthorizeFilter
整個過程從上到下就是這樣一個價值通路,並且已經包含了形式物件
從資源到許可權,角色,再到角色和使用者的繫結,再到授權整個體系,形成了系統架構
層級分解
首先從系統架構中找到實體物件:資源,許可權,角色,使用者
資源由 ResourceProvider 提供,分為 ActionResourceProvider 和 EntityResourceProvider
使用者和角色使用 ASP .NET Core Identity 的 UserManager 和 RoleManager
ASP .NET Core Identity 只包含使用者和角色,需要針對 Identity 做擴充套件,加上許可權
UIprotron.Security.Core 負責管理資源和許可權
UIprotron.Security.Identity 作為 Identity 的擴充套件,將資源和許可權加入到 Identity 中,相當於一個適配層
UIprotron.Security.ActionAccess 和 UIprotron.Security.EntityAccess 分別負責 Action 和 Entity 的許可權
大體上分為以下幾部分:
- ASP .NET Core Identity:使用者認證的庫
- UIprotron.Security.Identity:Core 與 Identity 的整合元件
- UIprotron.Security.Core:對資源和許可權的管理
- UIprotron.Security.ActionAccess:Action 資源發現和許可權控制
- UIprotron.Security.EntityAccess:Entity 資源發現和許可權控制
- UIprotron.Security.Store.EntityFramework:資源和許可權的 EF Core 持久層
洋蔥架構
- CoreAdapters:最核心最穩定的放最裡面
- Application Security.Identity:應用層,Identity 的擴充套件
- Action Access
- Entity Access
- EfResourceStore
對每一層進行拆分,將功能拆分為 Core,Models,Store 和 EFStore
課程連結
https://appsqsyiqlk5791.h5.xiaoeknow.com/v1/course/video/v_5f39bdb8e4b01187873136cf?type=2
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。
歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含連結: http://www.cnblogs.com/MingsonZheng/ ),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。
如有任何疑問,請與我聯絡 (MingsonZheng@outlook.com) 。