一、基本概念
1.權限管理
只要有用戶參與的系統一般都要有權限管理,權限管理實現對用戶訪問系統的控制,按照安全規則或者安全策略控制用戶可以訪問而且只能訪問自己被授權的資源。
權限管理包括用戶認證和授權兩部分。
2.用戶認證
用戶認證,用戶去訪問系統,系統要驗證用戶身份的合法性。
最常用的用戶身份驗證的方法:
(1)用戶名密碼方式
(2)指紋打卡機、
(3)基於證書驗證方法。
系統驗證用戶身份合法,用戶方可訪問系統的資源。
(1)用戶認證的流程
(2)關鍵對象
subject: 主體,理解為用戶,可能是程序,都要去訪問系統的資源,系統需要對subject進行身份認證。
principal: 身份信息,通常是唯一的,一個主體還有多個身份信息,但是都有一個主身份信息(primary principal)。
credential: 憑證信息,可以是密碼 、證書、指紋。
總結:主體在進行身份認證時需要提供身份信息和憑證信息。
3.用戶授權
用戶授權,簡單理解為訪問控制,在用戶認證通過后,系統對用戶訪問資源進行控制,用戶具有資源的訪問權限方可訪問。
流程:
4.權限模型
主體(賬號、密碼)
權限(權限名稱、資源id)
角色(角色名稱)
角色和權限關系(角色id、權限id)
主體和角色關系(主體id、角色id)
(1)基於角色份的訪問控制
系統角色包括: 部門經理、總經理(角色針對用戶來划分)。
系統代碼中實現:
//如果該user是部門經理則可以訪問if中的代碼
if(user.hasRole('部門經理')){
//系統資源內容
//用戶報表查看
}
問題:
角色針對人划分的,人作為用戶在系統中屬於活動內容,如果該 角色可以訪問的資源出現變更,需要修改你的代碼了,比如:需要變更為部門經理和總經理都可以進行用戶報表查看,代碼改為:
if(user.hasRole('部門經理') || user.hasRole('總經理') ){
//系統資源內容
//用戶報表查看
}
基於角色的訪問控制是不利於系統維護(可擴展性不強)。
(2)基於資源的訪問控制
資源在系統中是不變的,比如資源有: 類中的方法,頁面中的按鈕。
對資源的訪問需要具有permission權限,代碼可以寫為:
if(user.hasPermission ('用戶報表查看(權限標識符)')){
//系統資源內容
//用戶報表查看
}
上邊的方法就可以解決用戶角色變更不用修改上邊權限控制的代碼。
如果需要變更權限只需要在分配權限模塊去操作,給部門經理或總經理增或刪除權限。
建議使用基於資源的訪問控制實現權限管理。
5.粗粒度和細粒度權限
(1)粗粒度權限管理
粗粒度權限管理,對資源類型的權限管理。
資源類型比如:菜單、url連接、用戶添加頁面、用戶信息、類方法、頁面中按鈕。
粗粒度權限管理比如:超級管理員可以訪問戶添加頁面、用戶信息等全部頁面。
部門管理員可以訪問用戶信息頁面包括頁面中所有按鈕。
(2)細粒度權限管理
細粒度權限管理,對資源實例的權限管理。
資源實例就資源類型的具體化,比如:用戶id為001的修改連接,1110班的用戶信息、行政部的員工。
細粒度權限管理就是數據級別的權限管理。
細粒度權限管理比如:部門經理只可以訪問本部門的員工信息,用戶只可以看到自己的菜單,大區經理只能查看本轄區的銷售訂單。
粗粒度和細粒度例子
系統有一個用戶列表查詢頁面,對用戶列表查詢分權限,如果粗顆粒管理,張三和李四都有用戶列表查詢的權限,張三和李四都可以訪問用戶列表查詢。
進一步進行細顆粒管理,張三(行政部)和李四(開發部)只可以查詢自己本部門的用戶信息。張三只能查看行政部 的用戶信息,李四只能查看開發部門的用戶信息。細粒度權限管理就是數據級別的權限管理。
(3)如何實現粗粒度和細粒度權限管理
如何實現粗粒度權限管理?
粗粒度權限管理比較容易將權限管理的代碼抽取出來在系統架構級別統一處理。比如:通過springmvc的攔截器實現授權。
如何實現細粒度權限管理?
對細粒度權限管理在數據級別是沒有共性可言,針對細粒度權限管理就是系統業務邏輯的一部分,如果在業務層去處理相對比較簡單,如果將細粒度權限管理統一在系統架構級別去抽取,比較困難,即使抽取的功能可能也存在擴展不強。建議細粒度權限管理在業務層去控制。
比如:部門經理只查詢本部門員工信息,在service接口提供一個部門id的參數,controller中根據當前用戶的信息得到該 用戶屬於哪個部門,調用service時將部門id傳入service,實現該用戶只查詢本部門的員工。