Shiro是Apache的一個權限管理框架,鑑於不少人對權限管理的概念都不是很清楚,因此我在正式介紹Shiro前我會談談權限管理的概念。前端
只要有用戶參與的系統通常都要有權限管理,權限管理實現對用戶訪問系統的控制,按照安全規則或者安全策略控制用戶能夠訪問並且只能訪問本身被受權的資源。權限管理包括用戶認證和用戶受權兩部分java
用戶認證,用戶去訪問系統,系統要驗證用戶身份的合法性。最經常使用的用戶身份驗證的方法:一、用戶名密碼方式。二、指紋打卡機。三、基於證書驗證方法。只有當系統驗證用戶身份合法,用戶纔可訪問系統的資源。web
subject:主體,理解爲用戶,多是程序、網絡爬蟲等,都要去訪問系統的資源,系統須要對subject進行身份認證。spring
principal:身份信息,一般是惟一的,一個主體還有多個身份信息,可是都有一個主身份信息(primary principal)。數據庫
credential:憑證信息,能夠是密碼 、證書、指紋。緩存
總結:主體在進行身份認證時須要提供身份信息和憑證信息。安全
用戶受權,簡單理解爲訪問控制,在用戶認證經過後(注意只有當用戶認證經過後才能對用戶進行受權),系統對用戶訪問資源進行控制,用戶具備資源的訪問權限方可訪問。服務器
受權的過程理解爲:who對what(which)進行how操做。網絡
who:主體即subject,subject在認證經過後系統進行訪問控制。多線程
what(which):資源(Resource),subject必須具有資源的訪問權限纔可訪問該 資源。資源好比:系統用戶列表頁面、商品修改菜單、商品id爲001的商品信息。資源分爲資源類型和資源實例:系統的用戶信息就是資源類型,至關於java類;系統中id爲001的用戶就是資源實例,至關於new的java對象。
how:權限/許可(permission) ,針對資源的權限或許可,subject具備permission訪問資源,如何訪問/操做須要定義permission,權限好比:用戶添加、用戶修改、商品刪除。
對1.3.2節提到的主體、資源、權限經過數據模型表示,標準權限數據模型包括 :用戶(帳號和密碼)、角色(角色名稱)、權限(包括資源和權限)、用戶角色關係(用戶id、角色id)、角色權限關係(角色id、權限id)。以下圖:
而一般企業開發中將資源表和權限表合併爲一張權限表,以下圖:
上圖常被稱爲權限管理的通用模型,不過企業在開發中根據系統自身的特色還會對上圖進行修改,可是用戶、角色、權限、用戶角色關係、角色權限關係是須要去理解的。
用戶須要分配相應的權限纔可訪問相應的資源。權限是對於資源的操做許可。
一般給用戶分配資源權限須要將權限信息持久化,好比存儲在關係數據庫中。
把用戶信息、權限管理、用戶分配的權限信息寫到數據庫(權限數據模型)。
權限的控制分爲基於角色的訪問控制和基於資源的訪問控制。
基於角色的訪問控制:RBAC((role based access control)。好比:系統角色包括 :部門經理、總經理。(角色針對用戶來劃分)。
系統代碼中的實現爲:
1 2 3 4 5 |
//若是該user是部門經理則能夠訪問if中的代碼 if(user.hasRole('部門經理')){ //系統資源內容 //用戶報表查看 } |
基於角色的訪問控制出現的問題:角色針對人劃分的,人做爲用戶在系統中屬於活動內容,若是該 角色能夠訪問的資源出現變動,須要修改你的代碼了,好比:須要變動爲部門經理和總經理均可以進行用戶報表查看,代碼改成:
1 2 3 4 |
if(user.hasRole('部門經理') || user.hasRole('總經理') ){ //系統資源內容 //用戶報表查看 } |
可知基於角色的訪問控制是不利於系統維護(可擴展性不強)。
而對於基於資源的訪問控制:RBAC(Resource based access control)。由於資源在系統中是不變的,好比資源有:類中的方法,頁面中的按鈕。對資源的訪問須要具備permission權限,代碼能夠寫爲:
1 2 3 4 |
if(user.hasPermission ('用戶報表查看(權限標識符)')){ //系統資源內容 //用戶報表查看 } |
上邊的方法就能夠解決用戶角色變動不用修改上邊權限控制的代碼。若是須要變動權限只須要在分配權限模塊去操做,給部門經理或總經理增或刪除權限。因此在實際開發中咱們建議使用基於資源的訪問控制實現權限管理。
粗粒度權限管理:對資源類型的權限管理。資源類型好比:菜單、url鏈接、用戶添加頁面、用戶信息、類方法、頁面中按鈕。粗粒度權限管理好比:超級管理員能夠訪問戶添加頁面、用戶信息等所有頁面。部門管理員能夠訪問用戶信息頁面包括 頁面中全部按鈕。
細粒度權限管理:對資源實例的權限管理。資源實例就資源類型的具體化,好比:用戶id爲001的修改鏈接,1110班的用戶信息、行政部的員工。細粒度權限管理就是數據級別的權限管理。細粒度權限管理好比:部門經理只能夠訪問本部門的員工信息,用戶只能夠看到本身的菜單,大區經理只能查看本轄區的銷售訂單。
粗粒度和細粒度例子:系統有一個用戶列表查詢頁面,對用戶列表查詢分權限,若是粗顆粒管理,張三和李四都有用戶列表查詢的權限,張三和李四均可以訪問用戶列表查詢。
進一步進行細顆粒管理,張三(行政部)和李四(開發部)只能夠查詢本身本部門的用戶信息。張三隻能查看行政部 的用戶信息,李四隻能查看開發部門的用戶信息。細粒度權限管理就是數據級別的權限管理。
如何實現粗粒度權限管理?
粗粒度權限管理比較容易將權限管理的代碼抽取出來在系統架構級別統一處理。好比:經過springmvc的攔截器實現受權。
如何實現細粒度權限管理?
對細粒度權限管理在數據級別是沒有共性可言,針對細粒度權限管理就是系統業務邏輯的一部分,若是在業務層去處理相對比較簡單,若是將細粒度權限管理統一在系統架構級別去抽取,比較困難,即便抽取的功能可能也存在擴展不強。
建議細粒度權限管理在業務層去控制。好比:部門經理只查詢本部門員工信息,在service接口提供一個部門id的參數,controller中根據當前用戶的信息獲得該 用戶屬於哪一個部門,調用service時將部門id傳入service,實現該用戶只查詢本部門的員工。
Apache Shiro是Java的一個權限管理框架,相比Spring框架中的權限管理框架Spring Security,Spring Security和Spring的依賴過於緊密,沒有Shiro使用簡單,並且Shiro不依賴Spring,它不只能夠實現web應用的權限管理,還能夠實現c/s系統、分佈式系統權限管理。
Shiro屬於輕量框架,能夠幫助咱們完成:認證、受權、加密、會話管理、與Web集成、緩存等功能,因此愈來愈多企業項目開始使用Shiro。並且Shiro的API也是很是簡單,其基本功能點以下圖:
解釋:
記住一點:Shiro不會去維護用戶、維護權限,這些須要咱們本身去設計/提供;而後經過相應的接口注入給Shiro便可。
接下來咱們分別從外部和內部來看看Shiro的架構,對於一個好的框架,從外部來看應該具備很是簡單易於使用的API,且API契約明確;從內部來看的話,其應該有一個可擴展的架構,即很是容易插入用戶自定義實現,由於任何框架都不能知足全部需求。
從外部看Shiro,即從應用程序的角度來觀察如何使用Shiro完成工做。以下圖Apache官網爲咱們提供的一張Shiro的架構圖:
解釋:應用代碼直接交互的對象是Subject,也就是說Shiro的對外API核心就是Subject;圖中每一個API的含義:
也就是說對於咱們而言,最簡單的一個Shiro應用都是通過以下步驟:
一、應用代碼經過Subject來進行認證和受權,而Subject又委託給SecurityManager。
二、咱們須要給Shiro的SecurityManager注入Realm,從而讓SecurityManager能獲得合法的用戶及其權限進行判斷。
從以上也能夠看出,Shiro不提供維護用戶/權限,而是經過Realm讓開發人員本身注入。
架構圖以下:
分析: