注:該系列所有測試均在之前建立的Shiro3的Web工程的基礎上。
我們之前講解了Realm認證和認證器政策等知識,下面來講解Shiro中比較重要的知識:授權。
對于授權,也叫通路控制,即在應用中控制誰通路哪些資源(如通路頁面/編輯資料/頁面操作等)。
一、授權的幾個重要概念
在授權中需要了解幾個關鍵對象:主體(Subject)、資源(Resource)、權限(Permission)、角色(Role)。
(1) 主體(Subject):通路應用的使用者,在Shiro中使用Subject代表使用者。使用者隻有授權後才能通路
相應的資源。
(2) 資源(Resource):在應用中使用者可以通路的URL,比如通路JSP頁面、檢視/編輯某些資料,通路某個
業務方法,列印文本等等都是資源。使用者隻有授權後才可以通路。
(3) 權限(Permission):安全政策中的原子授權機關,通過權限我們可以表示在應用中使用者有沒有操作某個資源的
權利。即權限表示在應用中使用者能不能通路某個資源。如:通路使用者清單頁面檢視/新增/修改/删除使用者資料(即很
多時候都是CRUD(增删改查)式權限控制)等。權限代表了使用者有沒有操作某個資源的權利,即反應在某個資源上的
操作允不允許。
Shiro支援粗粒度權限(如使用者子產品的所有權限)和細粒度權限(操作某個使用者的權限,即執行個體級别的)。
(4) 角色(Role):權限的集合。一般情況下會賦予使用者角色而不是權限,即這樣使用者可以擁有一組權限,賦予權限
時比較友善。典型的如:項目經理、技術總監。CTO、開發工程師等都是角色,不同的角色擁有一組不同的權限。
二、Shiro授權方式
Shiro支援三種方式的授權:
(1)程式設計式:通過寫if/else授權代碼塊完成
if(subject.hasRole("admin")){
//有權限
}else{
//無權限
}
(2)注解式:通過在執行的Java方法上放置相應的注解完成,沒有權限将抛出相應的異常。
@RequiresRoles("admin")
public void hello(){
//有權限
}
(3)JSP/GSP标簽:在JSP/GSP頁面通過相應的标簽完成,如:
<shiro:hasRole name="admin">
<!--有權限-->
<shiro:hasRole>
三、Shiro授權使用的攔截器
回顧一下我們之前配置的Shiro測試工程的配置:
<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="/list.jsp"/>
<property name="unauthorizedUrl" value="/index.jsp"/>
<!--
配置哪些頁面需要受保護.
以及通路這些頁面需要的權限.
1). anon 可以被匿名通路
2). authc 必須認證(即登入)後才可能通路的頁面.
3). logout 登出
-->
<property name="filterChainDefinitions">
<value>
/login.jsp = anon
/userAuth/login = anon
/userAuth/logout = logout
# everything else requires authentication:
/** = authc
</value>
</property>
</bean>
可以看到,我們分别用了anon、authc和logout三個過濾器。而在Shiro中,内置了很多預設的攔截器,
比如身份驗證、授權等相關的。
預設攔截器可以參考org.apache.shiro.web.filter.mgt.DefaultFilter中的枚舉攔截器:
public enum DefaultFilter {
anon(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
}
其中分為三類攔截器:
1.身份驗證相關的

2.授權相關的
在這裡,我們實驗一下roles攔截器的作用。在我們之前的Shiro3工程下建立一個admin.jsp
和一個User.jsp頁面:
其中的代碼為:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>admin page</title>
</head>
<body>
This is Admin page. <br>
</body>
</html>
和
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>user page</title>
</head>
<body>
This is User page. <br>
</body>
</html>
然後在原來的登入成功後看到的list.jsp頁面中添加兩個超連結:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>首頁</title>
</head>
<body>
登入成功!歡迎通路首頁O(∩_∩)O
<a href="userAuth/logout" target="_blank" rel="external nofollow" >登出</a>
<br/><br/>
<a href="admin.jsp" target="_blank" rel="external nofollow" >Admin Page</a>
<br/><br/>
<a href="User.jsp" target="_blank" rel="external nofollow" >User Page</a>
</body>
</html>
當沒有權限時跳轉的頁面是index.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>提示</title>
</head>
<body>
抱歉,沒有權限通路該資源!<br>
</body>
</html>
我們的需求就是,admin.jsp頁面,隻允許有“admin”角色的使用者看到。
而User.jsp頁面,所有user權限使用者均可看到。如果沒有相關權限,Shiro會自動
跳轉至shiroFilter配置的unauthorizedUrl路徑。
首先我們在applicationContext.xml中的shiroFilter攔截器配置中添加roles攔截:
<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="/list.jsp"/>
<property name="unauthorizedUrl" value="/index.jsp"/>
<!--
配置哪些頁面需要受保護.
以及通路這些頁面需要的權限.
1). anon 可以被匿名通路
2). authc 必須認證(即登入)後才可能通路的頁面.
3). logout 登出
4). roles 角色過濾器
-->
<property name="filterChainDefinitions">
<value>
/login.jsp = anon
/userAuth/login = anon
/userAuth/logout = logout
/User.jsp = roles[user]
/admin.jsp = roles[admin]
# everything else requires authentication:
/** = authc
</value>
</property>
</bean>
上面為User.jsp和admin.jsp配置了角色攔截器,控制“user”和“admin”角色的人可以通路相關
頁面。
我們尚且沒有給任何使用者配置角色,那麼當任意一個使用者登入時:
分别點選上面的Admin Page以及UserPage,發現都沒有權限(跳轉我們的unauthorizedUrl指向的jsp):
證明我們的配置起到了作用。關于如何為使用者設定相關的角色,在後面的章節會進行深入學習。
3.其他
了解了上面的Shiro授權相關知識,就可以為後面的授權流程學習奠定了基礎。
轉載請注明出處:http://blog.csdn.net/acmman/article/details/78695263