1. 程式人生 > >Spring Security 實戰乾貨:圖解Spring Security中的Servlet過濾器體系

Spring Security 實戰乾貨:圖解Spring Security中的Servlet過濾器體系

## 1. 前言 我在[Spring Security 實戰乾貨:內建 Filter 全解析](https://www.felord.cn/spring-security-filters.html)對**Spring Security**的內建過濾器進行了羅列,但是**Spring Security**真正的過濾器體系才是我們瞭解它是如何進行"認證"、“授權”、“防止利用漏洞”的關鍵。 ## 2. Servlet Filter體系 這裡我們以**Servlet Web**為討論目標,**Reactive Web**暫不討論。我們先來看下最基礎的**Servlet**體系,在**Servlet**體系中客戶端發起一個請求過程是經過0到N個`Filter`然後交給`Servlet`處理。 ![servlet過濾器鏈](https://img2020.cnblogs.com/other/1739473/202007/1739473-20200706111603231-1307976421.png) `Filter`不但可以修改`HttpServletRequest`和`HttpServletResponse`,可以讓我們在請求響應的前後做一些事情,甚至可以終止過濾器鏈`FilterChain`的傳遞。 ```java 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進行了簡單的對比](https://www.felord.cn/pre-learn-spring-security-shiro.html)。**Spring Security**利用了**Spring IOC**和**AOP**的特性而無法脫離**Spring**獨立存在,而**Apache Shiro**可以獨立存在。所以今天我們要一探究竟,看看他們是如何結合的。 **Spring**結合**Servlet Filter**自然是要為**Servlet Filter**注入**Spring Bean**的特性,所以就搞出了一個抽象**Filter Bean**,這個抽象過濾器`GenericFilterBean`並不是在**Spring Security**下,而是**Spring Web**體系中,類圖如下: ![image-20200701162747774](https://img2020.cnblogs.com/other/1739473/202007/1739473-20200706111603427-514643250.png) 從類圖上看`Filter`介面已經被注入了多個**Spring Bean**的特性,納入了**Spring Bean**生命週期,使得**Spring IoC**容器能夠充分的管理`Filter`。 ## 4. DelegatingFilterProxy 我們希望**Servlet**能夠按照它自己的標準來註冊到過濾器鏈中工作,但是同時也希望它能夠被**Spring IoC**管理,所以Spring提供了一個`GenericFilterBean`的實現`DelegatingFilterProxy`。我們可以將原生的**Servlet Filter**或者**Spring Bean Filter**委託給`DelegatingFilterProxy`,然後在結合到**Servlet FilterChain**中。 ![DelegatingFilterProxy](https://img2020.cnblogs.com/other/1739473/202007/1739473-20200706111603688-1405642231.png) ## 5. SecurityFilterChain 針對不同符合[Ant Pattern](https://felord.cn/spring-security-ant-url.html)的請求可能會走不同的過濾器鏈,比如登入會去驗證,然後返回登入結果;管理後臺的介面走後臺的安全邏輯,應用客戶端的介面走客戶端的安全邏輯。**Spring Security**提供了一個`SecurityFilterChain`介面來滿足被匹配`HttpServletRequest`走特定的過濾器鏈的需求。 ```java public interface SecurityFilterChain { // 判斷請求 是否符合該過濾器鏈的要求 boolean matches(HttpServletRequest request); // 對應的過濾器鏈