深入淺出Spring Security(二):FilterChainProxy的創建過程

上篇回顧

  • 框架的核心是一個過濾器,這個過濾器名字springSecurityFilterChain類型FilterChainProxy
  • WebSecurityHttpSecurity都是建造者
  • WebSecurity構建目標是FilterChainProxy對象
  • HttpSecurity的構建目標僅僅是FilterChainProxy中的一個SecurityFilterChain
  • @EnableWebSecurity註解,導入了WebSecurityConfiguration
  • WebSecurityConfiguration中創建了建造者對象WebSecurity,和核心過濾器FilterChainProxy

WebSecurityConfiguration開始

WebSecurityConfiguration中需要關注兩個方法:

  1. setFilterChainProxySecurityConfigurer()方法

    創建了WebSecurity建造者對象,用於後面建造FilterChainProxy過濾器

  2. springSecurityFilterChain()方法

    調用WebSecurity.build(),建造出FilterChainProxy過濾器對象

WebSecurity的創建過程:setFilterChainProxySecurityConfigurer()方法

該方法負責收集配置類對象列表webSecurityConfigurers,並創建WebSecurity

  1. @Value("#{}") 是SpEl表達式通常用來獲取bean的屬性或者調用bean的某個方法。

  2. 方法執行時,會先得到webSecurityConfigurers並排序(所有實現了WebSecurityConfigurerAdapter的配置類實例)

  3. newwebsecurity對象,並使用Spring的容器工具初始化

  4. 判斷webSecurityConfigurers內元素的@Order是否有相同,相同的order會拋異常。

    默認order等於LOWEST_PRECEDENCE = 2147483647(參考Integer order = AnnotationAwareOrderComparator.lookupOrder(config)

  5. WebSecurityConfigurerAdapter的子類apply()放入websecurityList<SecurityConfigurer<O, B>> configurersAddedInInitializing中。

setFilterChainProxySecurityConfigurer()

下圖是通過AutowiredWebSecurityConfigurersIgnoreParentsgetWebSecurityConfigurers()方法,獲取所有實現WebSecurityConfigurer的配置類

getWebSecurityConfigurers

FilterChainProxy的創建過程:springSecurityFilterChain()方法

springSecurityFilterChain()方法中調用webSecurity.build()創建了FilterChainProxy

PS:根據下面代碼,我們可以知道如果創建的MySecurityConfig類沒有被sping掃描到,

框架會新new 出一個WebSecurityConfigureAdapter對象,這會導致我們配置的用戶名和密碼失效。

springSecurityFilterChain
springSecurityFilterChain()

我們繼續看FilterChainProxy的創建過程:

WebSecurity是一個建造者,所以我們去看這些方法build(); doBuild(); init(); configure(); performBuild();

build()方法定義在WebSecurity對象的父類AbstractSecurityBuilder中:

AbstractSecurityBuilder#build()

build()方法會調用WebSecurity對象的父類AbstractConfiguredSecurityBuilder#doBuild()

AbstractConfiguredSecurityBuilder#doBuild()

doBuild()先調用init();configure();等方法

我們上面已經得知了configurersAddedInInitializing裏是所有的配置類對象

如下圖,這裏會依次執行配置類的configure();init()方法

doBuild()最後調用了WebSecurity對象的perfomBuild(),來創建了FilterChainProxy對象

performBuild()裏遍歷securityFilterChainBuilders建造者列表

把每個SecurityBuilder建造者對象構建成SecurityFilterChain實例

最後創建並返回FilterChainProxy

performBuild()

securityFilterChainBuilders建造者列表是什麼時候初始化的呢

這時候要注意到WebSecurityConfigurerAdapter,這個類的創建了HttpSecurity並放入了securityFilterChainBuilders

securityFilterChainBuilders

WebSecurityConfigurerAdapter是一個安全配置器,我們知道建造者在performBuild()之前都會把循環調用安全配置器init();configure();方法,然後創建HttpSecurity並放入自己的securityFilterChainBuilders裏。

PS: 前面已經提到了,在WebSecurity初始化時,會依次將WebSecurityConfigurerAdapter的子類放入WebSecurity

public abstract class WebSecurityConfigurerAdapter implements
		WebSecurityConfigurer<WebSecurity> {
}
public interface WebSecurityConfigurer<T extends SecurityBuilder<Filter>> extends
		SecurityConfigurer<Filter, T> {
}

《深入淺出Spring Security(一):三句話解釋框架原理》

《深入淺出Spring Security(二):FilterChainProxy的創建過程》

《深入淺出Spring Security(三):FilterChainProxy的運行過程》

《深入淺出Spring Security(四):詳解WebSecurity與HttpSecurity》

《深入淺出Spring Security(五):認證和授權的過程》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章