1. 前言
我在Spring Security 實戰干貨:內置 Filter 全決議對Spring Security的內置過濾器進行了羅列,但是Spring Security真正的過濾器體系才是我們了解它是如何進行"認證"、“授權”、“防止利用漏洞”的關鍵,
2. Servlet Filter體系
這里我們以Servlet Web為討論目標,Reactive Web暫不討論,我們先來看下最基礎的Servlet體系,在Servlet體系中客戶端發起一個請求程序是經過0到N個Filter然后交給Servlet處理,

Filter不但可以修改HttpServletRequest和HttpServletResponse,可以讓我們在請求回應的前后做一些事情,甚至可以終止過濾器鏈FilterChain的傳遞,
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
// 請求被servlet 處理前
if(condition){
// 根據條件來進入下一個過濾器
chain.doFilter(request, response);
}
// 請求被執行完畢后處理一些事情
}
由于Filter僅影響下游Filters和Servlet,因此每個Filter呼叫的順序非常重要,Spring Security正是根據這個個特性來實作一系列的安全功能,接下來我們來看看它們是如何結合的,
3. GenericFilterBean
在該系列的文章開篇我對Spring Security和Shiro進行了簡單的對比,Spring Security利用了Spring IOC和AOP的特性而無法脫離Spring獨立存在,而Apache Shiro可以獨立存在,所以今天我們要一探究竟,看看他們是如何結合的,
Spring結合Servlet Filter自然是要為Servlet Filter注入Spring Bean的特性,所以就搞出了一個抽象Filter Bean,這個抽象過濾器GenericFilterBean并不是在Spring Security下,而是Spring Web體系中,類圖如下:

從類圖上看Filter介面已經被注入了多個Spring Bean的特性,納入了Spring Bean生命周期,使得Spring IoC容器能夠充分的管理Filter,
4. DelegatingFilterProxy
我們希望Servlet能夠按照它自己的標準來注冊到過濾器鏈中作業,但是同時也希望它能夠被Spring IoC管理,所以Spring提供了一個GenericFilterBean的實作DelegatingFilterProxy,我們可以將原生的Servlet Filter或者Spring Bean Filter委托給DelegatingFilterProxy,然后在結合到Servlet FilterChain中,

5. SecurityFilterChain
針對不同符合Ant Pattern的請求可能會走不同的過濾器鏈,比如登錄會去驗證,然后回傳登錄結果;管理后臺的介面走后臺的安全邏輯,應用客戶端的介面走客戶端的安全邏輯,Spring Security提供了一個SecurityFilterChain介面來滿足被匹配HttpServletRequest走特定的過濾器鏈的需求,
public interface SecurityFilterChain {
// 判斷請求 是否符合該過濾器鏈的要求
boolean matches(HttpServletRequest request);
// 對應的過濾器鏈
List<Filter> getFilters();
}

6. FilterChainProxy
不同的SecurityFilterChain應該是互斥而且平等的,它們之間不應該是上下游關系,

如上圖請求被匹配到不同的SecurityFilterChain然后在執行剩余的過濾器鏈,它們經過SecurityFilterChain的總流程是相似的,而且有些時候特定的一些SecurityFilterChain也需要被集中管理來實作特定一攬子的請求的過濾邏輯,所以就有了另外一個GenericFilterBean實作來做這個事情,它就是FilterChainProxy,它的作用就是攔截符合條件的請求,然后根據請求篩選出符合要求的SecurityFilterChain,然后鏈式的執行這些Filter,最后繼續執行剩下的FilterChain,
擴展閱讀:Spring Security 過濾器鏈
7. 總結
結合上面,最終上述這些概念的關系徹底搞清楚了,搞清楚過濾器的運作模式對于學習和使用Spring Security至關重要,

多多關注微信公眾號:碼農小胖哥 獲取更多的技術干貨,六月打榜結果已出請中獎的同學速度聯系我領取,另外七月打榜前三會送上熱門技術正版物體書籍, 打榜的要求只有一個關注、轉發、再看、點贊都可以增加自己的排名,
關注公眾號:Felordcn 獲取更多資訊
個人博客:https://felord.cn
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/150234.html
標籤:Java
