使用:org.apache.shiro.web.filter.authz.RolesAuthorizationFilter進行授權攔截
本文還是使用靜態的驗證方式,將在以後一步步進行數據庫查詢認證信息和授權信息,不過,爲了方便大家一步步學習和查看,還是先從靜態的方式開始吧。
perms(許可驗證)
org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
perms:例子/admins/user/**=perms[user:add:*],參數可以寫多個,多個時必須加上引號,並且參數之間用逗號分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],當有多個參數時必須每個參數都通過才通過,想當於isPermitedAll()方法。
/admins/user/**=perms[user:add:*]表示:要訪問【/admins/user/**】必須具有【user:add:* 】權限
在application-shiro.xml中配置URL所需要的權限:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/user/login.action" /> <!-- 沒有權限或者失敗後跳轉的頁面 -->
<property name="filterChainDefinitions">
<!-- , roles[admin], perms[document:read] -->
<value>
<!-- 對靜態資源設置匿名訪問 -->
/js/** = anon
/css/** = anon
/img/** = anon
/fonts/** = anon
/scripts/** = anon
/user/login.action = authc
/user/logout = logout
<!-- 進入後臺需要權限:admin:* -->
/backstage/** = perms[admin:*]
/user/** = user
</value>
</property>
</bean>
在Struts2中加入上面Shiro中過濾鏈的對應的鏈接的Action:
【Action可以不用配置處理方法的,這個大家應該都知道吧?】
<!-- 後臺 -->
<package name="backstage" namespace="/backstage" extends="struts-default">
<default-action-ref name="index" />
<action name="index">
<result>/WEB-INF/jsp/backstage/index.jsp</result>
</action>
</package>
自定義Realm的授權doGetAuthorizationInfo方法:
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//從principals獲取主身份信息
//將getPrimaryPrincipal()返回的值強制轉換爲真實身份信息【在上邊的doGetAuthenticationInfo()認證通過填充到SimpleAuthenticationInfo中的身份信息】
String userCode = (String) principals.getPrimaryPrincipal();
//根據身份信息獲取權限信息
//先鏈接數據庫。。。
//模擬從數據庫獲取數據
List<String> permissions = new ArrayList<String>();
permissions.add("admin:*");//用戶的創建權限
permissions.add("user:update");//用戶的修改
permissions.add("item:add");//商品的添加權限
//....等等權限
//查到權限數據,返回
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//將List裏面的權限填充進去
simpleAuthorizationInfo.addStringPermissions(permissions);
return simpleAuthorizationInfo;
}
在上面的代碼中,主要加入權限的是:
【以後這裏的權限數據是從數據庫中查回來的,測試的時候爲了更加直觀,所以就直接用了靜態寫死的方式展示給大家看。】
List<String> permissions = new ArrayList<String>();
permissions.add("admin:*");//用戶的創建權限
permissions.add("user:update");//用戶的修改
permissions.add("item:add");//商品的添加權限
//....等等權限
權限部分添加後,通過addStringPermissions方法將這個collection交給授權管理器進行權限的判斷。
//將List裏面的權限填充進去
simpleAuthorizationInfo.addStringPermissions(permissions);
測試流程:
1、在application-shiro.xml配置過濾的規則
<!-- 進入後臺需要權限:admin:* -->
/backstage/** = perms[admin:*]
2、用戶在認證通過後,請求【/backstage/**】即backstage命名空間中任意地址
被PermissionsAuthorizationFilter攔截,發現需要【admin:*】權限
3、PermissionsAuthorizationFilter調用Realm中的doGetAuthorizationInfo方法來獲取數據庫中正確的權限
4、PermissionsAuthorizationFilter對需要的權限【admin:*】和獲取的權限進行對比,如果【admin:*】在realm返回的權限列表中,則授權通過,否則沒有權限。在沒有權限的時候,我們就用下面對沒有權限的操作進行頁面跳轉。
配置沒有權限(授權失敗)頁面:
在使用Struts2時候,如果沒有訪問權限,就會報Status 401錯誤,畢竟401這個很不友好,那麼我們通過加入沒有權限訪問頁面,就可以防止出現401這個不友好的界面的問題。
需要在spring配置文件中,【shiroFilter】的bean中加入如下配置:
<!-- 通過unauthorizedUrl指定沒有權限操作時跳轉頁面-->
<property name="unauthorizedUrl" value="/refuse.jsp" />
存在的問題總結:
在applicationContext-shiro.xml中配置過濾器鏈,需要將全部的URl和權限對應起來進行配置,這種配置方式是比較麻煩的,不方便使用。
每次授權,都需要調用realm查詢數據庫,對於系統的性能具有很大的影響。設想:以後通過shiro的緩存來解決。
之後會一一處理這些問題。