Security提供了20多個filter,每個過濾器都提供特定的功能。這些filter在Spring Security filter過濾器鏈中的缺省順序由
org.springframework.security.config.http.SecurityFilters枚舉類型定義。通過filter機制,Spring Security實現了安全認
證和授權等安全相關工作。用戶通過配置文件,可以插入、替換或去除已知的filter,搭配自己的Spring Security filte過濾器鏈,
從而實現滿足自己特定應用需求的安全處理。
當auto-config="true"的情況下,默認會用到十一個過濾器,並且它們有一定的使用順序,如下圖。
默認配置的十一個過濾器介紹如下:
1.HttpSessionContextIntegrationFilter
位於過濾器頂端,第一個起作用的過濾器。
用途一,在執行其他過濾器之前,率先判斷用戶的session中是否已經存在一個SecurityContext了。
如果存在,就把SecurityContext拿出來,放到SecurityContextHolder中,供Spring Security的其他部分使用。
如果不存在,就創建一個SecurityContext出來,還是放到SecurityContextHolder中,供Spring Security的其他部分使用。
用途二,在所有過濾器執行完畢后,清空SecurityContextHolder,因為SecurityContextHolder是基於ThreadLocal的,
如果在操作完成后清空ThreadLocal,會受到服務器的線程池機制的影響。
2.LogoutFilter
只處理注銷請求,默認為/j_spring_security_logout。
用途是在用戶發送注銷請求時,銷毀用戶session,清空SecurityContextHolder,然后重定向到注銷成功頁面。
可以與rememberMe之類的機制結合,在注銷的同時清空用戶cookie。
3.AuthenticationProcessingFilter
處理form登陸的過濾器,與form登陸有關的所有操作都是在此進行的。
默認情況下只處理/j_spring_security_check請求,這個請求應該是用戶使用form登陸后的提交地址,form所需的其他參數可以參考:
此過濾器執行的基本操作時,通過用戶名和密碼判斷用戶是否有效,如果登錄成功就跳轉到成功頁面(可能是登陸之前訪問的受保護頁面,
也可能是默認的成功頁面),如果登錄失敗,就跳轉到失敗頁面。
<form action="${pageContext.request.contextPath}/j_spring_security_check" style="width:260px;text-align:center;"> <fieldset> <legend>登陸</legend> 用戶: <input type="text" name="j_username" style="width:150px;" value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}"/><br /> 密碼: <input type="password" name="j_password" style="width:150px;" /><br /> <input type="checkbox" name="_spring_security_remember_me" />兩周之內不必登陸<br /> <input type="submit" value="登陸"/> <input type="reset" value="重置"/> </fieldset> </form>
/j_spring_security_check,提交登陸信息的URL地址。
自定義form時,要把form的action設置為/j_spring_security_check。注意這里要使用絕對路徑,避免登陸頁面存放的頁面可能帶來的問題。
j_username,輸入登陸名的參數名稱。
j_password,輸入密碼的參數名稱
_spring_security_remember_me,選擇是否允許自動登錄的參數名稱。
可以直接把這個參數設置為一個checkbox,無需設置value,Spring Security會自行判斷它是否被選中。
4.DefaultLoginPageGeneratingFilter
此過濾器用來生成一個默認的登錄頁面,默認的訪問地址為/spring_security_login,這個默認的登錄頁面雖然支持用戶輸入用戶名,密碼,
也支持rememberMe功能,但是因為太難看了,只能是在演示時做個樣子,不可能直接用在實際項目中。
自定義登陸頁面
<http auto-config='true'> <intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" /> <intercept-url pattern="/**" access="ROLE_USER" /> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/" /> </http>
5.BasicProcessingFilter
此過濾器用於進行basic驗證,功能與AuthenticationProcessingFilter類似,只是驗證的方式不同。
添加basic認證,去掉auto-config="true",並加上<http-basic />
<http auto-config="true">
<http-basic />
<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
<intercept-url pattern="/" access="ROLE_USER" />
</http>
6.SecurityContextHolderAwareRequestFilter
此過濾器用來包裝客戶的請求。目的是在原始請求的基礎上,為后續程序提供一些額外的數據。
比如getRemoteUser()時直接返回當前登陸的用戶名之類的。
7.RememberMeProcessingFilter
此過濾器實現RememberMe功能,當用戶cookie中存在rememberMe的標記,此過濾器會根據標記自動實現用戶登陸,
並創建SecurityContext,授予對應的權限。
在配置文件中使用auto-config="true"就會自動啟用rememberMe
實際上,Spring Security中的rememberMe是依賴cookie實現的,當用戶在登錄時選擇使用rememberMe,系統就會在登錄成功后將為用戶生成一個唯一標識,
並將這個標識保存進cookie中,我們可以通過瀏覽器查看用戶電腦中的cookie。
8.AnonymousProcessingFilter
為了保證操作統一性,當用戶沒有登陸時,默認為用戶分配匿名用戶的權限。
在配置文件中使用auto-config="true"就會啟用匿名登錄功能。在啟用匿名登錄之后,如果我們希望允許未登錄就可以訪問一些資源,可以在進行如下配置。
<http auto-config='true'> <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" /> <intercept-url pattern="/**" access="ROLE_USER" /> </http>
設置成 ROLE_ANONYMOUS 也可以。
<http auto-config='true'> <intercept-url pattern="/" filters="none" /> <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" /> <intercept-url pattern="/**" access="ROLE_USER" /> </http>
filters="none"表示當我們訪問“/”時,是不會使用任何一個過濾器去處理這個請求的,它可以實現無需登錄即可訪問資源的效果,
但是因為沒有使用過濾器對請求進行處理,所以也無法利用安全過濾器為我們帶來的好處,最簡單的,這時SecurityContext內
再沒有保存任何一個權限主體了,我們也無法從中取得主體名稱以及對應的權限信息。
9.ExceptionTranslationFilter
此過濾器的作用是處理中FilterSecurityInterceptor拋出的異常,然后將請求重定向到對應頁面,或返回對應的響應錯誤代碼。
10.SessionFixationProtectionFilter
防御會話偽造攻擊。
解決session fix的問題其實很簡單,只要在用戶登錄成功之后,銷毀用戶的當前session,並重新生成一個session就可以了。
<http auto-config='true' session-fixation-protection="none"> <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" /> <intercept-url pattern="/**" access="ROLE_USER" /> </http>
session-fixation-protection的值共有三個可供選擇,none,migrateSession和newSession。默認使用的是migrationSession
11.FilterSecurityInterceptor
用戶的權限控制都包含在這個過濾器中。
功能一:如果用戶尚未登陸,則拋出AuthenticationCredentialsNotFoundException“尚未認證異常”。
功能二:如果用戶已登錄,但是沒有訪問當前資源的權限,則拋出AccessDeniedException“拒絕訪問異常”。
功能三:如果用戶已登錄,也具有訪問當前資源的權限,則放行。
注:資料來源於網絡。