1. 概述
Spring Security 基於 Servlet 過濾器鏈。每個過濾器都有特定的職責,並且根據配置,過濾器可以被添加或刪除。
在本教程中,我們將討論查找已註冊的 Spring Security 過濾器不同的方法。
2. 安全調試
首先,我們啓用安全調試,這將記錄每個請求的詳細安全信息。
我們可以使用 debug 屬性啓用安全調試:
@EnableWebSecurity(debug = true)這樣一來,當向服務器發送請求時,所有請求信息都會被記錄下來。
我們還可以查看整個安全過濾鏈。
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
UsernamePasswordAuthenticationFilter
// ...
]3. 日誌記錄
接下來,我們將通過啓用 FilterChainProxy 的日誌記錄功能來查找安全過濾器。
我們可以通過在 application.properties 中添加以下行來啓用日誌記錄:
logging.level.org.springframework.security.web.FilterChainProxy=DEBUG以下是相關日誌:
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 5 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
...4. 通過編程獲取過濾器程序
現在,我們將瞭解如何通過編程方式獲取已註冊的安全過濾器。
我們將會使用 FilterChainProxy 來獲取安全過濾器。
首先,讓我們自動注入 springSecurityFilterChain Bean:
@Autowired
@Qualifier("springSecurityFilterChain")
private Filter springSecurityFilterChain;在這裏,我們使用了名為 @Qualifier,其類型為 Filter,代替了 FilterChainProxy。這是因為 WebSecurityConfiguration 中方法 springSecurityFilterChain() 的返回值類型為 Filter,而非 FilterChainProxy。
接下來,我們將此對象轉換為 FilterChainProxy,並調用 getFilterChains() 方法:
public void getFilters() {
FilterChainProxy filterChainProxy = (FilterChainProxy) springSecurityFilterChain;
List<SecurityFilterChain> list = filterChainProxy.getFilterChains();
list.stream()
.flatMap(chain -> chain.getFilters().stream())
.forEach(filter -> System.out.println(filter.getClass()));
}以下是一個示例輸出:
class org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter
class org.springframework.security.web.context.SecurityContextPersistenceFilter
class org.springframework.security.web.header.HeaderWriterFilter
class org.springframework.security.web.authentication.logout.LogoutFilter
class org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
...請注意,自 Spring Security 3.1 版本起,<em style="font-style: italic;">FilterChainProxy</em> 的配置使用一個包含多個 <em style="font-style: italic;">SecurityFilterChain</em> 的列表。然而,大多數應用程序只需要一個 <em style="font-style: italic;">SecurityFilterChain</em>。
5. 重要 Spring Security 過濾器
最後,讓我們來了解一些重要的安全過濾器:
- UsernamePasswordAuthenticationFilter:處理身份驗證,默認響應“/login” URL
- AnonymousAuthenticationFilter:當 SecurityContextHolder 中不存在身份驗證對象時,它會創建一個匿名身份驗證對象並將其放入其中
- FilterSecurityInterceptor:訪問被拒絕時,拋出異常
- ExceptionTranslationFilter:捕獲 Spring Security 異常
6. 結論
在本文中,我們探討了如何通過編程方式和日誌來查找已註冊的 Spring Security 過濾器。