在我本身的一個在web項目使用了shiro的Filter,讓shiroFilter來代理整個web的FiltershiroFilter的大體配置以下:java
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="/" /><!-- 訪問須要認證的地址時,沒有認證跳轉的地址,默認爲login.jsp --> <property name="unauthorizedUrl" value="homePage" /> <!-- 登陸後,沒有訪問權限將跳轉到homePage --> <property name="filterChainDefinitions"> <!-- **表示匹配0個或多個路徑 ,*表示匹配0個或多個字符串,?表示匹配一個字符 --> <value> /preLogin = anon /toLogin = anon /userregister = anon /registerpage = anon /static/** = anon /login = anon /logout = logout /analysis/test = authc /analysis/test1 = authc,perms[admin:edit] <!--要有 admin:edit的權限 --> /** = user <!-- 主要針對rememberMe功能 ,當使用authc時,仍是要認證才能訪問 --> </value> </property> </bean>
在web.xml中shiroFilter的配置以下:web
<filter> <filter-name>shiroFilter</filter-name> <!-- DelegatingFilterProxy做用是自動到spring容器查找名字 爲shiroFilter(filter-name)的bean並把全部Filter的操做委託給它 --> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
同時在項目中還在web.xml中指定了一個項目歡迎頁面。代碼以下:spring
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>
而在歡迎頁面是一個jsp的跳轉標籤,用來跳轉到真正項目的首頁。index.jsp以下:apache
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <jsp:forward page="/preLogin" />
這裏跳轉的preLogin就是項目真正的首頁。
同時在springMVC中也配置了相關攔截器用來判斷用戶是否登陸,若未登陸則跳轉到登陸界面。攔截代碼以下:session
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String urlPath = request.getRequestURL().toString(); if(urlPath.matches(Const.StaticPath)) { //訪問的url是靜態資源 return true; } else { //訪問其餘的非靜態資源的url,當前僅判斷用戶是否登陸,若未登陸則跳轉到登陸界面 User user = (User)sessionUtil.getSessionAttribute(Const.currentUser); if(user != null) { //用戶已登陸 return true; } else { //用戶未登陸 response.sendRedirect(request.getContextPath() + Const.Login); return false; } } //return true; }
由於剛開始學習shiro因此這幾個攔截訪問混在一塊兒就搞不清楚誰先訪問誰後訪問,以及shiro斷定訪問權限後再如何跳轉。app
web的過濾器與springMVC攔截器的訪問順序參考http://blog.csdn.net/chenleixing/article/details/44573495。
經過這篇博客能夠知道過濾器Filter的優先級是要大於springMVC的攔截器Interceptor的。或者說,當有訪問來到時,是先執行Filter裏的邏輯,而後在執行Interceptor的。而shiro的Filter會代理web的Filter,因此會先執行shiro的過濾器在執行springMVC的攔截器。在給程序打斷點,F6一步一步執行的過程當中也能夠發現這一點。
那麼在web.xml中設置的歡迎頁面與shiroFilter誰會先執行呢?
再回答這個問題的時候,要先看看我寫的shiroFilter的配置。jsp
<property name="loginUrl" value="/" /><!-- 訪問須要認證的地址時,沒有認證跳轉的地址,默認爲login.jsp --> <property name="unauthorizedUrl" value="homePage" /> <!-- 登陸後,沒有訪問權限將跳轉到homePage -->
用戶沒有認證時(即沒有執行subject.login()方法)如有權限的限制,會到轉到根目錄即index.jsp頁面,而index.jsp頁面又會立刻跳轉到preLogin頁面。當我在頁面上輸入http://localhost:8080/spiderAndAnalysis/(即:訪問項目的根目錄/時)我就搞不清楚究竟是經過Filter訪問的preLogin頁面仍是直接先訪問的index.jsp頁面未通過Filter。因此後來我將< property name=」loginUrl」 value=」/」 />的value換成了analysis,再次訪問項目根目錄,發現此次直接跳轉到了analysis頁面。因此shiroFilter的優先級高於歡迎界面,即在配置了shiroFilter管理web訪問時,全部請求都要先通過shiroFilter,再通過其餘過濾器攔截器等ide
在配置shiroFilter的時候用到了loginUrl,unauthorizedUrl以及filterChainDefinitions等參數。我的理解的配置含義:
loginUrl:當用戶未認證(即:未執行subject.login()函數登陸成功),若此時訪問有訪問權限的url時,會跳轉到loginUrl指定的登陸界面,若訪問無權限的url則會直接訪問。
以本文的配置爲例:若直接訪問preLogin ,toLogin ,userregister這類沒有訪問權限的url時,將直接訪問,不用跳轉。若訪問analysis/test這個url,而且用戶未登陸時,將跳轉到loginUrl指定的登陸界面。
unauthorizedUrl:當用戶認證了,訪問了沒有權限訪問的url時會跳轉到unauthorizedUrl指定的地址。例如:用戶A已經登陸可是用戶A只有admin:add權限時,用戶A訪問analysis/test1這個須要admin:edit權限的url時,將跳轉到unauthorizedUrl指定的homePage地址。函數