1. 概述
在本快速教程中,我們將重點介紹為 Spring Security 過濾器鏈編寫自定義過濾器的過程。
2. 創建過濾器
Spring Security 默認提供了一些過濾器,這些過濾器通常就足夠使用。
當然,有時需要通過創建新的過濾器來在鏈中使用,以實現新的功能。
我們首先將實現 org.springframework.web.filter.GenericFilterBean。
GenericFilterBean 是一個 Spring 增強的 javax.servlet.Filter 實現。
我們只需要實現一個方法:
public class CustomFilter extends GenericFilterBean {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
3. 使用過濾器在安全配置中
我們可以選擇使用 XML 配置或 Java 配置來將過濾器添加到 Spring Security 配置中。
3.1. Java 配置
我們可以通過創建 SecurityFilterChain bean 來程序化地註冊過濾器。
例如,它與在 addFilterAfter 方法上一個 HttpSecurity 實例上工作:
@Configuration
public class CustomWebSecurityConfigurerAdapter {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.addFilterAfter(
new CustomFilter(), BasicAuthenticationFilter.class);
return http.build();
}
}
有幾種可能的辦法:
- addFilterBefore(filter, class) 之前添加一個 filter,在指定 class 的位置之前。
- addFilterAfter(filter, class) 之後添加一個 filter,在指定 class 的位置之後。
- addFilterAt(filter, class) 在指定 filter class 的位置上添加一個 filter。
- addFilter(filter) 添加一個 filter,它必須是 Spring Security 提供的一個實例或擴展類之一。
3.2. XML 配置
我們可以使用 custom-filter 標籤和 這些名稱 中的一個來使用名稱指定我們過濾器的位置。
例如,它可以由 after 屬性指定:
<http>
<custom-filter after="BASIC_AUTH_FILTER" ref="myFilter" />
</http>
<beans:bean id="myFilter" class="com.baeldung.security.filter.CustomFilter"/>
以下是指定我們過濾器在鏈中確切位置的屬性:
- after 描述了在鏈中將自定義過濾器放置在立即之後哪個過濾器之後。
- before 定義了我們的過濾器應該在鏈中放置在哪個過濾器的前面。
- position 允許通過自定義過濾器替換標準過濾器在明確位置。
4. 只在受保護端點應用 Spring Security 過濾器
現代應用程序通常同時提供公共端點和受保護端點。在全局應用自定義 Spring Security 過濾器可能會導致公共端點不必要的處理。為了解決這個問題,我們可以使用 Spring Security 的 SecurityFilterChain 和 RequestMatcher,將過濾器專門針對受保護端點。@Bean
public SecurityFilterChain securedFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
authorizationManagerRequestMatcherRegistry.requestMatchers("/secured/**").authenticated())
.httpBasic(Customizer.withDefaults());
http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
return http.build();
}此配置確保安全設置僅應用於匹配 /secured/** 的端點,如 requestMatchers(“/secured/**”) 中指定。
`addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class)` 行確保自定義過濾器在 BasicAuthenticationFilter 之後應用,這意味着它只會執行在基本身份驗證過程之後。
這種方法允許在受保護端點上進行有針對性的安全處理,而不會影響公共端點。所有對 /secured/** 的請求都需要身份驗證,如 .authorizeHttpRequests() 中強制執行。
通過使用自定義 SecurityFilterChain,我們可以隔離這些安全設置,保持應用程序的安全模塊化和高效。 此設置可以防止公共端點上的不必要開銷,並確保為受保護路徑(例如身份驗證入口點中的自定義失敗響應)提供定製的身份驗證處理。
5. 結論
在本文中,我們創建了一個自定義過濾器並將其連接到 Spring Security 過濾器鏈中。