在看此小節前,您可能需要先看:http://www.cnblogs.com/conswin/p/7478557.html
緊接上一篇,在上一篇我們簡單實現了一個Springboot的小程序,但我們發現隨便訪問那個頁面,都無需登錄即可訪問,我們希望在沒有登錄的情況下,需要跳轉到login頁面進行登錄后才能訪問,這個時候Shiro就要閃亮登場了。
四、集成Shiro,進行用戶授權。
集成Shiro可分為如下幾個步驟:
1、pom.xml中添加Shiro依賴
2、注入ShiroFilterFactory和SecurityManage
3、身份認證
4、權限控制
接下來逐一進行實現。
1、pom.xml中添加Shiro依賴
<!-- shiro spring. --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency>
2、注入ShiroFilterFactory和SecurityManage
我們在上一節說過,Shiro幾個核心的類,第一就是ShiroFilterFactory,第二就是SecurityManager,那么最簡單的配置就是注入這兩個類就ok了,那么如何注入呢?看如下代碼:
package com.kfit.config.shiro; import java.util.LinkedHashMap; import java.util.Map; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Shiro 配置 * Apache Shiro 核心通過 Filter 來實現,就好像SpringMvc 通過DispachServlet 來主控制一樣。 既然是使用 Filter 一般也就能猜到,是通過URL規則來進行過濾和權限校驗,所以我們需要定義一系列關於URL的規則和訪問權限。 * * @author Angel(QQ:412887952) * @version v.0.1 */ @Configuration public class ShiroConfiguration { /** * ShiroFilterFactoryBean 處理攔截資源文件問題。 * 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的,以為在 * 初始化ShiroFilterFactoryBean的時候需要注入:SecurityManager * Filter Chain定義說明 1、一個URL可以配置多個Filter,使用逗號分隔 2、當設置多個過濾器時,全部驗證通過,才視為通過 3、部分過濾器可指定參數,如perms,roles * */ @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){ System.out.println("ShiroConfiguration.shirFilter()"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 必須設置 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); //攔截器. Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); //配置退出過濾器,其中的具體的退出代碼Shiro已經替我們實現了 filterChainDefinitionMap.put("/logout", "logout"); //防止登錄成功之后下載favicon.ico filterChainDefinitionMap.put("/favicon.ico", "anon"); filterChainDefinitionMap.put("/static/**", "anon"); //<!-- 過濾鏈定義,從上向下順序執行,一般將 /**放在最為下邊 -->:這是一個坑呢,一不小心代碼就不好使了; //<!-- authc:所有url都必須認證通過才可以訪問; anon:所有url都都可以匿名訪問--> filterChainDefinitionMap.put("/**", "authc"); // 如果不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登錄成功后要跳轉的鏈接 shiroFilterFactoryBean.setSuccessUrl("/index"); //未授權界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); returnshiroFilterFactoryBean; } @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); return securityManager; } }
這里說下:ShiroFilterFactory中已經由Shiro官方實現的過濾器:
Shiro內置的FilterChain
Filter Name |
Class |
anon |
org.apache.shiro.web.filter.authc.AnonymousFilter |
authc |
org.apache.shiro.web.filter.authc.FormAuthenticationFilter |
authcBasic |
org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter |
perms |
org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter |
port |
org.apache.shiro.web.filter.authz.PortFilter |
rest |
org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter |
roles |
org.apache.shiro.web.filter.authz.RolesAuthorizationFilter |
ssl |
org.apache.shiro.web.filter.authz.SslFilter |
user |
org.apache.shiro.web.filter.authc.UserFilter |
anon:所有url都都可以匿名訪問;
authc: 需要認證才能進行訪問;
user:配置記住我或認證通過可以訪問;
這幾個是我們會用到的,在這里說明下,其它的請自行查詢文檔進行學習。
這時候我們運行程序,訪問/index頁面我們會發現自動跳轉到了login頁面,當然這個時候輸入賬號和密碼是無法進行訪問的。下面這才是重點:任何身份認證,如何權限控制。
3、身份驗證
在認證、授權內部實現中都有提到,最終的處理都是交由Realm進行處理的,因為在Shiro中最終是通過Realm來獲取應用程序的用戶、角色以及權限信息的。Realm是專用於安全框架的DAO。
認證實現:
Shiro的認證最終由Realm執行,這時會調用Realm的Authentication(token)方法,此方法主要執行以下操作:
①、檢查提交的令牌token信息
②、根據令牌信息從數據庫中獲取用戶信息
③、對用戶信息進行匹配驗證
④、驗證通過將返回一個封裝了用戶信息的AuthenticationInfo實例
⑤、驗證失敗則拋出AuthenticationException異常
而我們程序要做的就是自定義一個Realm類,繼承AuthorizingRealm抽象類,重載doAuthenticationInfo()方法,重新獲取用戶信息的方法。
既然要進行身份權限控制,少不了創建以下相關表了:
第一、用戶信息表:在用戶表中保存了用戶的基本信息,賬號、密碼、姓名,性別等。
第二、權限表(資源+控制權限):這個表中主要是保存了用戶的URL地址,權限信息
第三、角色表:在這個表重要保存了系統存在的角色
第四、角色-權限關聯表(每個角色都有什么權限可以進行操作)