Shiro(授權Authorization)

JasonTam發表於2018-08-14

什麼是授權?

  • 即該使用者是否有許可權訪問某個資源.(即校驗許可權)

Shiro許可權的實現方式

1. 硬編碼方式:實現授權訪問校驗.
  • 在自定義中的realm中的授權方法中進行編寫程式碼.
  • 根據傳進來的PrincipalCollection獲取使用者物件.
  • 該授權方法的返回值是AuthorizationInfo,該物件是一個介面,因此我們需要建立它的實現類,SimpleAuthorizationInfo.
  • 使用該類的方法

image

addRole 對應action 中的subject.checkRole方法.

/**
* 授權
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

User user = (User) principalCollection.getPrimaryPrincipal();

SimpleAuthorizationInfo sai  =  new SimpleAuthorizationInfo();
sai.addStringPermission("部門管理");

return sai;
}
複製程式碼
  • 訪問部門列表前需要進行許可權校驗
 @Action(value = "deptAction_list")
    public String toList() {

        Subject subject = SecurityUtils.getSubject();

        subject.checkPermission("部門管理");

        return "toList";
    }
複製程式碼
  • 這裡通過主體subject,提供使用者的許可權資訊.並將使用者的許可權資訊通過方法與Realm中的進行校驗.

image

image

使用到的方法 區別
subject.isPermitted() 返回的是一個boolean,有許可權則返回true,沒有返回false.該方法需要我們自己處理沒有許可權後要處理的事
subject.checkPremission 該方法如果沒有許可權會直接報錯

以上的兩個方法的作用是一樣的,都是校驗使用者是否有許可權訪問資源.但第一個方法需要自己進行判斷.第二個方法我們只需把異常處理了就可以了.

2. 過濾器配置(與Spring整合的配置檔案中配置)

特點:許可權校驗是通過配置檔案配置實現,因此許可權校驗與業務程式碼完全解耦.

  • 在applicationContext-shiro.xml中的配置

  • 格式為: 左邊為需要進行許可權校驗的url 右邊為perms[url所需要的許可權]

/sysadmin/deptAction_list = perms[部門列表]
/** = authc
複製程式碼

如果該使用者沒有許可權,會跳轉到錯誤頁面:

是因為在配置檔案上我們配置了未授權的跳轉頁面

<!--未授權校驗的頁面-->
<property name="unauthorizedUrl" value="/login.jsp"/>
複製程式碼
<!--1. 建立shiroFilterFactoryBean-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<!--認證失敗跳轉的頁面-->
<property name="loginUrl" value="/login.jsp"/>
<!--認證成功的頁面.如果程式碼中指定了,以程式碼跳轉的地址為準,通常會以登入成功跳轉的頁面為準-->
<property name="successUrl" value="/home.jsp"/>
<!--未授權校驗的頁面-->
<property name="unauthorizedUrl" value="/login.jsp"/>

<!--過濾器鏈-->
<property name="filterChainDefinitions">
<value>
    /index.jsp* = anon
    /home* = anon
    /sysadmin/login/login.jsp* = anon
    /sysadmin/login/loginAction_logout* = anon
    /login* = anon
    /logout* = anon
    /components/** = anon
    /css/** = anon
    /img/** = anon
    /js/** = anon
    /plugins/** = anon
    /images/** = anon
    /js/** = anon
    /make/** = anon
    /skin/** = anon
    /stat/** = anon
    /ufiles/** = anon
    /validator/** = anon
    /resource/** = anon
    /sysadmin/deptAction_list = perms[部門列表]
    /** = authc
</value>
</property>
</bean>
複製程式碼

資源路徑問題:如果第一位的過濾所匹配的資源路徑為/**的話,因為/**匹配的是所有資源路徑,所以下面的過濾器中的資源路徑都不會再匹配了.只會執行第一個過濾器.因此配置資源路徑為/**的過濾器一般放在過濾器鏈的最後.

注意:授權過濾器需要放在認證過濾器之前.否則會失效(資源路徑為/**的情況下)

方式3:註解

使用shiro註解實現許可權校驗步驟:

  1. 開啟註解支援
  2. 使用註解

根據官方文件說明,開啟註解支援我們需要在shiro與Spring的配置檔案中,配置三個Bean.

image

  • 開啟註解支援
<!--開啟shiro授權校驗註解支援-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>
複製程式碼

注意:這裡使用到了depend-on,表示建立該物件需要depend-on的物件,因此在建立該物件之前先建立depend-on的物件,然後再建立當前物件.

  • 使用註解(@RequiresPermissions)

注意:這個註解要定義到Service上.當使用struts註解開發的時候如果將shiro的註解寫到action上會對struts有干擾.傳入的service可能會有問題.如果想在action上使用shiro註解,那麼使用struts.xml 配置檔案來進行開發.

  @RequiresPermissions("部門列表")
    @Override
    public Page<Dept> findAll(Specification<Dept> spec, Pageable pageable) {
        return deptDao.findAll(spec, pageable);
    }
複製程式碼
  • 該種方式校驗到使用者沒有該許可權訪問資源,不會報錯而是以下的這種效果:

image

方式4 :shiro的自定義標籤

使用前需要把標籤庫匯入

<%@ taglib prefix="shiro"  uri="http://shiro.apache.org/tags" %>
複製程式碼
  • 使用案列:

<shiro:hasPermission name="">這個標籤會去到我們自定義的Realm中進行許可權的校驗.匹配我們name的值與Realm中的值

<%@ taglib prefix="shiro"  uri="http://shiro.apache.org/tags" %>
<html>
<head>
    <title>Title</title>
</head>
<script type="text/javascript" src="${ctx}/js/jquery-1.11.3.min.js"></script>
<body>
<shiro:hasPermission name="部門列表">
<a href="#">部門列表</a> <br>
</shiro:hasPermission>

<shiro:hasPermission name="刪除部門">
<a href="#">刪除部門</a> <br>
</shiro:hasPermission>

<shiro:hasPermission name="新增部門">
<a href="#">新增部門</a> <br>
</shiro:hasPermission>

<shiro:hasPermission name="修改部門">
<a href="#">修改部門</a> <br>
</shiro:hasPermission>
</body>
</html>
複製程式碼

這種方式多用於Jsp頁面上.用於動態的顯示選單.

總結:

  1. 在Service上面使用的shiro的授權方式:硬編碼,註解.
  2. 在Action上面使用的shiro的授權方式:
  • 如果開發使用的是struts.xml的配置檔案, 並且沒有引入struts註解開發支援包,action上做許可權校驗可以使用硬編碼,註解,過濾器.

  • 如果開發使用的是struts註解開發支援包,action上做許可權校驗可以使用硬編碼,過濾器.

  1. 在JSp上的許可權校驗:使用第四種方式,使用shiro的自定義標籤

如果有什麼地方說得不正確,大家可以在評論寫下一起交流。希望我的文章對你有幫助。點個贊阿兄dei!

相關文章