天天看點

【Shiro權限管理】14.Shiro授權

注:該系列所有測試均在之前建立的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.身份驗證相關的

【Shiro權限管理】14.Shiro授權

2.授權相關的

【Shiro權限管理】14.Shiro授權

在這裡,我們實驗一下roles攔截器的作用。在我們之前的Shiro3工程下建立一個admin.jsp

和一個User.jsp頁面:

【Shiro權限管理】14.Shiro授權

其中的代碼為:

<%@ 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”角色的人可以通路相關

頁面。

我們尚且沒有給任何使用者配置角色,那麼當任意一個使用者登入時:

【Shiro權限管理】14.Shiro授權
【Shiro權限管理】14.Shiro授權

分别點選上面的Admin Page以及UserPage,發現都沒有權限(跳轉我們的unauthorizedUrl指向的jsp):

【Shiro權限管理】14.Shiro授權

證明我們的配置起到了作用。關于如何為使用者設定相關的角色,在後面的章節會進行深入學習。

3.其他

【Shiro權限管理】14.Shiro授權

了解了上面的Shiro授權相關知識,就可以為後面的授權流程學習奠定了基礎。

轉載請注明出處:http://blog.csdn.net/acmman/article/details/78695263

繼續閱讀