通用權限管理系統的總結梳理及技術細節
一、基本權限管理系統
基本的權限管理系統,基本遵循RBAC(Role-Base Accese Control)的模式
基本模式,class和action分開
但我們實際業務中,我們多把class和action合在一起
如果是內容類,比如cms這種,我們一般采用拆開的方式,因為這種資源-操作拆分的方式有意義。
如果是審批類,比如oa系統這種,我們一般采用合并的方式。
二、通用權限管理系統
當業務越來越多,都需要權限管理系統的時候,通用權限管理系統就顯得迫在眉睫。
而通用權限管理系統中,粒度劃分尤為重要。
1.粒度劃分
權限的最小粒度,一般以一個接口為一條權限。
比如 /bbs/create (代表論壇發帖) ?這種接口為最小粒度,好處是便于管理。
而如果是 /bbs/create?cid=123&pid=456 這種,我們還是按照 /bbs/create 這種粒度劃分,而里面的參數,一般的做法是在create這個接口里面再單獨做權限判斷。保證最小粒度的權限足夠簡單,權限管理部分職責單一,而與業務強耦合的功能放在業務里做。
也就是可以分成 平臺權限和業務權限。
2.結構圖
如圖所示,通用權限管理系統中,用戶可能會是域賬號登陸,外部的域賬號只與用戶關聯與系統無關。
為了適應不同場景,用戶、應用、角色三者會關聯成一張表。
這個表的作用是告訴系統,哪個用戶在哪個應用下對應哪一個角色。
角色跟資源的關系還是跟普通的權限系統保持一致。
如 用戶A 在 OA 下是 管理員,用戶A 在 ACL 下是 用戶。
通過這個對應關系,基本可以滿足各種不同的應用場景。
而數據資源作為可選項,在某些場景下也可能存在。
如用戶A 在 DZZ 游戲下是管理員,用戶A 在DQY 游戲下是GM。
這里需要關注的一點是,這個表基本都是一個用戶對應一個游戲為一條數據,而不會一個用戶對應多個游戲為一條數據。這是因為首先權限系統比較復雜,我們這么做為了使權限管理更加簡單不使問題復雜化。另一個原因是真實使用場景中,這種一對多的關系比較少,復用率很低,而且變化的時候不靈活。
三、實際應用場景的思考
對于B端產品,可能會有多個系統部署在用戶機器上,比如一個機器上有OA和ERP系統,兩套系統都需要賬戶體系和權限管理系統,這個時候就可以用通用權限管理系統互相打通。但是通用權限系統貌似減少了開發成本,但是也有可能維護成本極高,要使用不同的系統之間的差異。
因此,設計通用權限管理系統的時候,往往通用權限系統只做一部分最簡單的,最基礎的權限控制,而跟業務耦合的權限管理則在各自系統本身的業務邏輯里面。
所以,才有了文章開頭的粒度問題。
我們的粒度一般分到URI級別,每一個請求沒有個URI都是一個資源,一個資源對應一條權限。
比如用戶發帖這種問題,發帖接口可能是一個接口,但是里面還會涉及到用戶是否可以發圖片的這種權限。
這種情況下,比較推薦的做法是用戶發帖還是一個權限,由通用權限系統處理,而發圖片權限,則再由業務邏輯判斷。class+action這一層最好職責單一,不摻雜業務判斷,這樣比較好管理,同時保持通用權限管理系統的純粹性。
四、關于菜單
在實際場景中,每個項目都有菜單,當業務場景比較單一的情況下,菜單也可以做到通用權限管理系統中統一處理。
一個菜單對應一個資源,也可以對應多個資源
一般流程為:應用獲取菜單總數據,查詢這個用戶信息,再通過權限系統查詢這個用戶uid對應每個資源是否有權限,然后洗掉沒權限的菜單,留下這個用戶在這個應用下的菜單。
如圖所示,菜單可以只跟用戶關聯,所有的操作都是從用戶這個緯度進行查詢,這也也保持了基礎權限管理系統的完整性。
當然,菜單可以不做在通用權限管理系統里做在業務層里,具體問題具體分析。
五、其他
現實應用場景中,對于應用來說,簡單的做法是用戶的相關權限操作都去請求通用權限管理系統,能操作就返回true,不能操作返回false。但如果需要的權限請求非常多,也可以一次性全部取全,再業務層自己處理。
實際開發中,權限管理原則大部分是視圖不做強限制,數據強限制。
用戶如果足夠多,且權限差不多是,會分成用戶組進行管理。
用戶權限的繼承基本在實際場景下不會考慮,因為一旦后期用戶權限發生改變,牽連過大。
而用戶權限的互斥一般只在業務在使用,保證通用權限管理系統的可維護性和通用性,特殊需求業務自己要求就好了。