轉載本文需註明出處:微信公衆號EAWorld,違者必究。
引言:
權限控制在每一個應用中都必不可少,類似卻又總不盡相同。有沒有一種比較通用的設計甚至框架,可讓咱們不用每次都去重複造這個輪子呢?本文主要是向你們介紹下咱們的應用基礎框架coframe,以及在權限控制方面的一些設計與實踐。
目錄:
1、應用基礎框架簡介
2、應用權限模型設計
3、應用權限控制
1、應用基礎框架簡介
相信不少同窗都有過這樣的經歷,剛作完一個項目,開始一個新項目的時候,發現基礎能力又要從新開發一遍,用戶,登錄,菜單,機構人員,權限管理等等。重複的工做枯燥而沒有價值,卻不得不作。可否來個什麼框架,能夠直接提供這些開箱即用的基礎能力?
回答固然是有,咱們這裏把這種包含了應用基礎能力與通用業務模塊的框架,稱之爲應用基礎框架。它就像一個半成品的車架,已經有了基本的架子,輪子,發動機,方向盤等,基本上已經能夠跑了。可是車子更多的其它能力,還等待人後續去完善。
完整的應用基礎框架,應當包括應用後端基礎框架與前端展示基礎框架(包括 web 或移動)。這樣二者配合使用,才能直接爲應用提供開箱即用的業務能力。
不論先後端,咱們認爲框架能夠分爲如下四層:
1.基礎依賴層:基本上定義的框架的技術棧,採用什麼語言,什麼框架,依賴哪些基礎庫或組件等
2.基礎能力層:定義的是基礎能力,後端包括對異常的定義,國際化的處理,ORM模型的抽像等等,前端則是對菜單,路由,通訊等的框架化封裝,通用基礎組件的抽取等
3.通用業務層:實現通用的一些業務能力,如用戶管理,登入登出,權限控制等等
4.用戶業務層:這一層交由用戶去擴展,實現各自已的業務能力
Coframe就是咱們構建的這樣一套應用基礎框架。它的後端框架,基於 spring boot + spring security + jpa, 前端基於 vue + iview。
前端
Coframe應用基礎框架能力圖譜vue
coframe提供的基礎能力有:
1.組織機構:機構樹管理,機構管理,崗位管理,工做組管理,員工管理
2.用戶認證:用戶管理,本地認證,單點登錄(需與 iam 集成)
3.權限管理:權限模板管理,角色模板管理,角色管理,資源組管理,菜單管理,功能管理
4.數據字典:字典類型管理,字典項管理,字典國際化,導入導出
5.日誌管理:統一日誌接口,日誌全索
全部這些能力開箱即用。
下面咱們重點分享一下關於應用權限方面咱們的一些設計與實踐
2、應用權限模型設計
首先,咱們要了解一下,什麼是權限。咱們認爲,權限就是用戶對某些資源的控制能力。因此,模型上咱們就有了一個抽像的資源概念。
資源按類型具化,多是用戶在門戶上可見的菜單,或者是頁面上可見可點擊的某些按鈕,或者用戶在應用後端能夠調用的某個接口等。
用戶經過角色,與這些資源創建了關聯,咱們才能在系統中經過用戶找到這些資源,而後對它進行控制。
所以,用戶,角色,資源的關係,就是一個用戶可分配多個角色,一個角色,能夠關聯多個資源。以下圖所示:
爲了方便角色進行資源受權的管理,咱們又提出了幾個服務於它們的概念:角色模板,權限模板,資源組。
資源組,顧名思義,就是資源的分組。它是一個樹狀模型,目前主要設計使用了三層。頂層的表明着某一塊的資源總集,好比某個子系統的資源總集。
權限模板,它經過關聯多個頂層的資源組,能夠表明着某個範圍內的可受權資源總集。角色模板關聯着權限模板,從它的這個資源集合中挑出了一部分。
角色則是在建立的時候,複製模板的這些資源受權。但它後續能夠修改,整個可受權資源仍爲權限模板表明的總集。
資源的受權如上圖所示。頂層的資源組表明着某一塊的資源總集,第二層則表明不一樣的資源類型,如菜單,功能,環境等。第三層表明着模塊,好比機構管理模塊的菜單。第三層的資源組之下,才關聯具體的資源。對角色或者角色模板進行資源受權配置時,只須要找到對應的資源類型與模塊,再找到相應的資源,點擊是否勾選便可完成受權,很是地直觀。
用戶是如何與資源關聯起來的呢?以下圖,這裏咱們假設了一個示例。
某應用集成了 coframe,其下又分了三個子系統。爲了方便資源的管理,咱們爲每一個子系統設置了一個頂層的資源組,而後爲它配置了下層資源組與資源。而後,咱們設置了兩個權限模板,其中一個負責 coframe 與子系統一的資源,另外一個則負責三個子系統的資源。基於兩個權限模板,咱們分別建立了角色一與角色二。三個用戶中,用戶一分配了角色一,用戶二分配了角色一與二,用戶三分配了角色二。用戶一可分配 coframe 與子系統一中的資源,用戶二可分配全部資源,用戶三則只能分配三個子系統的資源。這樣,資源的組合與隔離,會變得至關方便與直觀。
3、應用權限控制
咱們認爲,應用的權限控制能夠分爲以下四類:
1.菜單:用戶在應用門戶中可見哪些菜單能夠經過權限控制
2.按鈕/連接:用戶在門戶頁面中,哪些按鈕可見可操做,可經過權限控制
3.接口調用:不經過門戶,直接經過客戶端進行接口調用,接口是否容許調用能夠經過權限控制
4.數據:用戶是否可見某些數據,可否操做能夠經過權限控制
菜單控制
菜單的控制其實比較簡單。用戶登錄成功後,前端會再來取一次用戶的菜單項。後端服務根據用戶分配的角色中,包含的菜單資源,在門戶中組織出他所持有的菜單樹。
可是菜單的組織過程,卻也能夠有一些不一樣。這裏咱們一種稱爲動態結構,另外一種爲靜態結構。
動態結構首先要求菜單自己爲樹狀結構,且菜單對應的頁面(vue 中叫路由),圖標等也記錄在菜單中。整個菜單的層次結構,由菜單自己的樹狀結構表現。這種結構的好處是菜單配置很是靈活,菜單能夠徹底經過頁面操做進行定製。這種結構適合常常須要動態變動的系統,且菜單配置人員對前端要很是地熟悉。
另外一種靜態菜單結構,則菜單隻須要一個平鋪關係便可。菜單的層級,順序,路由,圖標等由前端定義,後端只定義用戶能夠用到哪些菜單。缺點是菜單定製不夠靈活,但優勢也很明顯,很是便於前端開發,先後端分工更明確。
按鈕/連接控制
有些系統中,會將按鈕的權限與後端功能的權限分開設計爲兩個模型,但 coframe 中這兩個合爲一個叫作功能的模型。功能有惟一編碼,這個編碼在按鈕上可控制按鈕的顯示,在方法上能夠控制方法可否調用。
按鈕的控制也比較簡單,特別是組件化的前端開發框架中。只須要爲全部的按鈕組件添加一個權限碼定義,在頁面渲染時,判斷一下當前用戶是否擁有這個權限碼,有則顯示此按鈕,沒有則將按鈕從父組件中刪除。
接口調用控制
在接口調用控制上,咱們考慮過使用現成的一些控制方法,如 spring method security。可是它只能控制到角色級,雖然能夠規則匹配,但仍然不夠靈活。因此,咱們基於功能編碼,自行設計了一套。
它的基本原理是,咱們使用 annotation,在每一個須要控制的方法,添加了調用此方法須要的功能編碼。方法被調用時,咱們經過 aspect 對方法進行攔截,取得調用它所要求的功能碼。而後咱們在當前用戶所擁有全部的功能碼(在用戶登錄時已查詢出來放在 context 中了)中進行對比,若是存在就容許方法調用,不然拋出無權調用的異常。
鑑於有些須要控制的方法可能在父類中,因此咱們定義了兩個 annotation,一個定義在類上,能夠配置父類上須要控制的方法。另外一個定義在方法上,配置方法控制的權限碼。查詢方法調用所需權限碼時,優先在方法上找到,找不到再到類上去查找。
爲了方便集成的應用實現接口調用控制,咱們定義了一個抽象的方法權限切片處理類,封裝了對方法調用的攔截過程。應用只須要繼承這個類,配置須要攔截哪些接口便可。
數據權限控制
數據權限,咱們認爲數據權限 = 數據可見控制 + 數據操做控制。
而數據操做控制,經過按鈕控制與接口調用控制組合,基本上可達到想要的效果。
那數據可見如何控制呢?咱們概括爲兩種:成員法與資源受權法。
成員法,就是用戶若是爲某個領域的成員,則他就能夠看到這個領域,以及這個領域中的資源。如何實現呢?簡單一點的辦法,就是用戶的某個角色,屬於這個領域,就能夠認爲這個用戶是這個領域的成員。像租戶隔離,devops 中的項目隔離,其實就是用的這種方法。
資源受權法,將某個精確的資源受權角色,或者直接授予用戶。成員法實現數據可見控制有一個問題,就是粗度太大,很差實現更精確更細粒度的資源可見控制。要實現更細粒度的,可使用資源受權法。但粒度細也就表明着管理複雜,孰好孰壞須要權衡後去使用。
關於做者:秦雙春,現任普元雲計算架構師。曾在PDM,雲計算,數據備份,移動互聯相關領域公司工做,十年以上IT工做經驗。曾爲科企桌面虛擬化產品的核心工程師,愛數容災備份雲櫃系統設計師,萬達信息的食安管理與追溯平臺開發經理。國內IAAS雲計算的早期實踐者,容器技術專家。
關於EAWorld:微服務,DevOps,數據治理,移動架構原創技術分享。長按二維碼關注!web