Spring Security過濾器鏈體系

碼農小胖哥發表於2022-02-10

以下摘自胖哥分享的 2022開工福利教程。

在學習Spring Security的時候你有沒有下面這兩個疑問:

  • Spring Security的登入是怎麼配置的?
  • Spring Security的訪問控制是什麼機制?

SpringBootWebSecurityConfiguration

上面兩個疑問的答案就在配置類SpringBootWebSecurityConfiguration中。你可以按照下面這個思維導圖去理解這個自動配置:
SpringBootWebSecurityConfiguration

SpringBootWebSecurityConfigurationSpring Boot應用提供了一套預設的Spring Security配置。

	@Bean
	@Order(SecurityProperties.BASIC_AUTH_ORDER)
	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
		http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();
		return http.build();
	}

這裡的配置為:所有的請求都必須是認證使用者發起的,同時開啟表單登入功能以及Http Basic Authentication認證功能。 我們訪問/foo/bar時需要登入認證並且能夠進行表單登入就是這個配置起作用了。這個是我們日常開發需要自定義的,在HttpSecurity相關的文章中胖哥也進行了講解。這個SecurityFilterChain到底是什麼呢?

SecurityFilterChain

從上面看得出HttpSecurity就是一個構建類,它的使命就是構建出一個SecurityFilterChain

public interface SecurityFilterChain {
   //  當前請求是否匹配
	boolean matches(HttpServletRequest request);
    // 一攬子過濾器組成的有序過濾器鏈
	List<Filter> getFilters();
}

當一個請求HttpServletRequest進入SecurityFilterChain時,會通過matches方法來確定是否滿足條件進入過濾器鏈。就好比你是VIP走的是VIP通道,享受的是VIP的一系列待遇;你是普通使用者,就走普通使用者的通道並享受普通使用者的待遇。

不管使用者是哪種角色,都走的是一個過濾器鏈,一個應用中存在1-nSecurityFilterChain。那誰來管理多個SecurityFilterChain呢?

記住這個公式HttpSecurity ->SecurityFilterChain

FilterChainProxy

FilterChainProxy是一個GenericFilterBean(即使Servlet Filter又是Spring Bean),它管理了所有注入Spring IoC容器的SecurityFilterChain。在我剛接觸Spring Security的時候是這樣配置FilterChainProxy的:

    <bean id="myfilterChainProxy" class="org.springframework.security.web.FilterChainProxy">
        <constructor-arg>
            <util:list>
                <security:filter-chain pattern="/do/not/filter*" filters="none"/>
                <security:filter-chain pattern="/**" filters="filter1,filter2,filter3"/>
            </util:list>
        </constructor-arg>
    </bean>

根據不同的請求路徑匹配走不同的SecurityFilterChain。下面是示意圖:

後面還會對接觸這個類,現在你只需要明白上面這個圖就行了。

請注意:在同一過濾器鏈中不建議有多個FilterChainProxy例項,而且不應將其作為單純的過濾器使用,它只應該承擔管理SecurityFilterChain的功能。

DelegatingFilterProxy

Servlet 容器和Spring IoC容器之間的Filter生命週期並不匹配。為了讓Spring IoC容器管理Filter的生命週期,FilterChainProxy便交由Spring Web下的DelegatingFilterProxy來代理。而且FilterChainProxy不會在新增到應用程式上下文的任何過濾器Bean上呼叫標準Servlet過濾器生命週期方法,FilterChainProxy的生命週期方法會委託給DelegatingFilterProxy來執行。而DelegatingFilterProxy作為Spring IoCServlet的聯結器存在。

簡單總結

上面的三個概念非常重要,涉及到Spring Security的整個過濾器鏈體系。但是作為初學者來說,能看懂多少就看懂多少,不要糾結哪些沒有理解,因為目前學習階段的層次達不到是非常正常的。但是等你學完了Spring Security之後,這幾個概念一定要搞明白。

關注公眾號:Felordcn 獲取更多資訊

個人部落格:https://felord.cn

相關文章