亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

首頁 慕課教程 Spring Security Spring Security Spring Security 安全過濾器

Spring Security 安全過濾器

1. 前言

上一節中我們了解到了 Spring Security 安全框架是由一系列有序的安全過濾器組成的,本節將重點討論 Spring Security 內置安全過濾器的順序及含義。

Spring 將自己體系內的過濾器交由「過濾器代理 FilterChainProxy」管理,Spring Security 在「過濾器代理 FilterChainProxy」中加入了「安全過濾器鏈 SecurityFilterChain」實現安全保護功能。

在 Spring Security 各個模塊中,內置已實現了一系列的「安全過濾器」,可以滿足常見的認證、鑒權等功能需求。

在 Spring Security 5.3.2 中,共內置了 33 個安全過濾器。

本節主要討論 Spring Security 內置的安全過濾器。

2. 內置安全過濾器

2.1 內置安全過濾器的聲明

Spring Security 中的 SecurityFilterChain 對象,是通過 HttpSecurity 類來使用,它還提供了安全過濾器增、減的調用接口。

如前文所述,安全過濾器的執行順序是至關重要的,而順序的確定是由 FilterComparator 對象實現的。

FilterComparator 類的全路徑為 org.springframework.security.config.annotation.web.builders.FilterComparator。

在其構造的時候配置了過濾器的基本順序,代碼如下:

FilterComparator() {
  FilterComparator.Step order = new FilterComparator.Step(100, 100);
  this.put(ChannelProcessingFilter.class, order.next());
  this.put(ConcurrentSessionFilter.class, order.next());
  this.put(WebAsyncManagerIntegrationFilter.class, order.next());
  this.put(SecurityContextPersistenceFilter.class, order.next());
  this.put(HeaderWriterFilter.class, order.next());
...
  this.put(SessionManagementFilter.class, order.next());
  this.put(ExceptionTranslationFilter.class, order.next());
  this.put(FilterSecurityInterceptor.class, order.next());
  this.put(SwitchUserFilter.class, order.next());
}

注意,以上 FilterComparator 中的定義僅作為內置過濾器排序的依據,并不等于過濾器的真正注入。

除了內置的過濾器外,當我們需要添加自定義過濾器的時候,也需要依賴 FilterComparator 對象完成順序的配置。實際開發時可用以下方法完成向指定順位插入過濾器的功能:http.addFilterAfter、http.addFilterBeforehttp.addFilter、http.addFilterAthttpHttpSecurity 實例)。

另一方面,HttpSecurity 還為各個內置過濾器提供了配置接口。例如:針對 HeaderWriterFilter 提供了 headers() 方法,用于獲取或為 HeaderWriterFilter 配置參數,例如設置響應緩存時效 Expires 等 。HttpSecurity 在構建時,會根據已有的配置信息逐一對 Filter 進行實例化。HttpSecurity 還完成了對請求地址的配置,通過 RequestMatcherConfigurer 對象使請求地址與 Filter 匹配。

2.2 內置過濾器總覽

圖片描述

內容過濾器總覽
Spring Security 內置了 33 種安全過濾器,其順序、名稱及作用如下表所示:
順序號 過濾器名稱 簡述
1 ChannelProcessingFilter 檢查 web 請求通道,如:http、https
2 ConcurrentSessionFilter 檢查 Session 狀態,更新 Session 最后訪問時間
3 WebAsyncManagerIntegrationFilter 關聯 Spring Web 上下文和 Spring Security 上下文
4 SecurityContextPersistenceFilter 從 Session 構建 SecurityContext
5 HeaderWriterFilter 往請求頭或響應頭里寫入信息
6 CorsFilter 跨域請求頭
7 CsrfFilter 跨站請求偽造
8 LogoutFilter 注銷過濾器
9 OAuth2AuthorizationRequestRedirectFilter OAuth2 請求重定向
10 Saml2WebSsoAuthenticationRequestFilter SAML2 單點登錄認證請求過濾器
11 X509AuthenticationFilter X509 認證過濾器
12 AbstractPreAuthenticatedProcessingFilter 預認證處理
13 CasAuthenticationFilter 單點認證過濾器
14 OAuth2LoginAuthenticationFilter OAuth2 認證過濾器
15 Saml2WebSsoAuthenticationFilter SAML2 單點登錄認證過濾器
16 UsernamePasswordAuthenticationFilter 用戶名密碼認證過濾器
17 ConcurrentSessionFilter 檢查 Session 狀態,更新 Session 最后訪問時間。第二次出現。
18 OpenIDAuthenticationFilter Open ID 認證過濾器
19 DefaultLoginPageGeneratingFilter 生成 /login 頁面
20 DefaultLogoutPageGeneratingFilter 生成 /logout 頁面
21 DigestAuthenticationFilter 數字簽名認證過濾器
22 BearerTokenAuthenticationFilter Bearer Token 認證過濾器
23 BasicAuthenticationFilter 基本身份認證過濾器
24 RequestCacheAwareFilter 緩存請求狀態過濾器
25 SecurityContextHolderAwareRequestFilter 安全上下文請求輔助過濾器
26 JaasApiIntegrationFilter JAAS 認證授權過濾器
27 RememberMeAuthenticationFilter 實現記住我功能
28 AnonymousAuthenticationFilter 匿名認證過濾器
29 OAuth2AuthorizationCodeGrantFilter OAuth2 認證授權碼
30 SessionManagementFilter 管理 Session
31 ExceptionTranslationFilter 異常事件處理過濾器
32 FilterSecurityInterceptor 動態權限配置
33 SwitchUserFilter 切換賬戶

2.3 常用內置過濾器的具體說明

內置過濾器的參數設置通過 HttpSecurity 相應的配置方法完成。

2.3.1 ChannelProcessingFilter

ChannelProcessingFilter 的用于檢測請求的通道,例如 HttpHttps 等,可以實現訪問請求在不同通道間的跳轉。

ChannelProcessingFilter 的配置通過 HttpSecurity.requiresChannel() 方法獲取。

例如:強制使用 Https 通道訪問。

http.requiresChannel().antMatchers("/users").requiresSecure();

2.3.2 ConcurrentSessionFilter

此過濾器在默認情況下出現兩次,其工作內容大致分兩步:

  1. 判斷 Session 是否存在,如果存在則獲取,否則結束;
  2. 判斷 Session 是否過期,如果過期則執行退出操作,否則更新 Session 時間。

ConcurrentSessionFilter 的配置通過 HttpSecurity.sessionManagement() 方法獲取。

例如:設置 Session 無效時的跳轉 URL。

http.sessionManagement().invalidSessionUrl("/login");

2.3.3 WebAsyncManagerIntegrationFilter

WebAsyncManagerIntegrationFilter 用于關聯 SecurityContext 上下文。

此過濾器無配置公布的方法。

2.3.4 SecurityContextPersistenceFilter

SecurityContextPersistenceFilter 用于從 Session 構建 SecurityContext。具體分為兩步:

  1. 請求開始時,將 SecurityContextRepository 中的 SecurityContext 對象存入 SecurityContextHolder;
  2. 請求完成時,清理 SecurityContextHolder 中的 SecurityContext 對象,并產生新的 SecurityContext 對象放入到 SecurityContextRepository 中,以保證并發環境下的數據一致性。

SecurityContextPersistenceFilter 的配置通過 HttpSecurity.securityContext() 方法獲取。

2.3.5 HeaderWriterFilter

HeaderWriterFilter 用于往請求頭或響應頭里寫入信息。

HeaderWriterFilter 的配置通過 HttpSecurity.headers() 方法獲取。默認支持的 Header 包括:

Header [name: X-Content-Type-Options, values: [nosniff]]
Header [name: X-XSS-Protection, values: [1; mode=block]]
Header [name: Cache-Control, values: [no-cache, no-store, max-age=0, must-revalidate]]
Header [name: Pragma, values: [no-cache]]
Header [name: Expires, values: [0]]

2.3.6 CorsFilter

CorsFilter 用于配置跨域請求策略。當一個請求中,來源與目標的協議、主機名、端口三者任一不同,即為跨域,在實際開發中如果遇到類似 header is present on the requested resource. 的錯誤時,往往是因為跨域配置不正確導致。

CorsFilter 的配置通過 HttpSecurity.cors() 方法獲取。例如,禁用跨域驗證:

http.cors().disable();

2.3.7 CsrfFilter

CsrfFilter 用于驗證消息來源,防范跨站請求偽造,此項功能需要前端的配合。

CsrfFilter 的配置通過 HttpSecurity.csrf() 方法獲取。例如,禁用 Csrf:

http.csrf().disable();

2.3.8 LogoutFilter

LogoutFilter 用于注銷登錄狀態。

LogoutFilter 的配置通過 HttpSecurity.logout() 方法獲取。例如,設置退出后的跳轉頁面。

http.logout().logoutSuccessUrl("/login");

2.3.9 UsernamePasswordAuthenticationFilter

UsernamePasswordAuthenticationFilter 用于處理用戶名、密碼認證。

UsernamePasswordAuthenticationFilter 的配置通過 HttpSecurity.formLogin() 方法獲取。例如,設置用戶名參數為「mobile」:

http.formLogin().usernameParameter("mobile")

UsernamePasswordAuthenticationFilter Spring Security 認證中較為常用的過濾器,我們會在后續章節重點展開。

2.3.10 ExceptionTranslationFilter

ExceptionTranslationFilter 用于異常事件處理。異常事件有前述過濾器拋出,異常共分為 2 類,一類是認證異常,另一類是權限異常。

ExceptionTranslationFilter 的配置通過 HttpSecurity.exceptionHandling() 方法獲取。

ExceptionTranslationFilter 同樣較為常用,將在后續章節中重點展開。

3 增加自定義的 Filter

在 HttpSecurity 對象中增加自定義 Filter 可用于實現認證方式的擴展等場景,擴展 Filter 有兩步很重要,第一是實現 javax.servlet.Filter 接口;第二是指定新過濾器的位置。

例如,擴展自定義接口 SimpleFilter。

  1. 自定義接口類
public class SimpleFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("In SimpleFilter");
    }
}
  1. 加入到指定位置,比如加在 UsernamePasswordAuthenticationFilter 之前
http.addFilterBefore(new SimpleFilter(), UsernamePasswordAuthenticationFilter.class);

4. 小結

本節我們介紹了 Spring Security 過濾器的作用及其順序,主要的知識點有:

  • Spring Security 通過擴展 Spring 過濾器實現安全相關業務邏輯;
  • Spring Security 目前原生實現了 33 個過濾器,每個過濾器有固定的順序及應用場景;
  • Spring Security 可以的插入自定義的過濾器,并且指定過濾器的位置。

Spring Security 過濾器幾乎是所有安全功能的核心,在后續章節中還會圍繞過濾器展開討論。下節我們將介紹 Spring Security 的異?;厥諜C制。