三句話解釋框架原理
- 整個框架的核心是一個過濾器,這個過濾器名字叫
springSecurityFilterChain
類型是FilterChainProxy
- 核心過濾器裏面是
過濾器鏈
(列表),過濾器鏈
的每個元素都是一組URL對應一組過濾器
WebSecurity
用來創建FilterChainProxy
過濾器,HttpSecurity
用來創建過濾器鏈的每個元素。
框架接口設計
關注兩個東西:
建造者
和配置器
框架的用法就是通過
配置器
對建造者
進行配置
框架用法是寫一個自定義配置類,繼承
WebSecurityConfigurerAdapter
,重寫幾個configure()
方法
WebSecurityConfigurerAdapter
就是Web安全配置器
的適配器對象
// 安全建造者
// 顧名思義是一個builder構造器,創建並返回一個類型爲O的對象
public interface SecurityBuilder<O> {
O build() throws Exception;
}
// 抽象安全建造者
public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> {
private AtomicBoolean building = new AtomicBoolean();
private O object;
public final O build() throws Exception {
// 限定build()只會進行一次!
if (this.building.compareAndSet(false, true)) {
this.object = doBuild();
return this.object;
}
throw new AlreadyBuiltException("This object has already been built");
}
// 子類需要重寫doBuild()方法
protected abstract O doBuild() throws Exception;
}
// 配置後的抽象安全建造者
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
extends AbstractSecurityBuilder<O> {
// 實現了doBuild()方法,遍歷configurers進行init()和configure()。
protected final O doBuild() throws Exception {
synchronized (configurers) {
buildState = BuildState.INITIALIZING;
beforeInit();
init();
buildState = BuildState.CONFIGURING;
beforeConfigure();
configure();
buildState = BuildState.BUILDING;
O result = performBuild();
buildState = BuildState.BUILT;
return result;
}
}
// 它的子類HttpSecurity和WebSecurity都實現了它的performBuild()方法!!!
protected abstract O performBuild() throws Exception;
// 主要作用是將安全配置器SecurityConfigurer注入到屬性configurers中,
private void configure() throws Exception {
Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
for (SecurityConfigurer<O, B> configurer : configurers) {
configurer.configure((B) this);
}
}
}
// 安全配置器,配置建造者B,B可以建造O
// 初始化(init)SecurityBuilder,且配置(configure)SecurityBuilder
public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
void init(B builder) throws Exception;
void configure(B builder) throws Exception;
}
// Web安全配置器,配置建造者T,T可以建造web過濾器
public interface WebSecurityConfigurer<T extends SecurityBuilder<Filter>>
extends SecurityConfigurer<Filter, T> {
}
// Web安全配置器的適配器
// 配置建造者WebSecurity,WebSecurity可以建造核心過濾器
public abstract class WebSecurityConfigurerAdapter
implements WebSecurityConfigurer<WebSecurity> {
}
// 用於構建FilterChainProxy的建造者
public final class WebSecurity
extends AbstractConfiguredSecurityBuilder<Filter, WebSecurity>
implements
SecurityBuilder<Filter>, ApplicationContextAware {
}
// 用於構建SecurityFilterChain的建造者
public final class HttpSecurity
extends AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
implements
SecurityBuilder<DefaultSecurityFilterChain>,
HttpSecurityBuilder<HttpSecurity> {
}
總結:
- 看到
建造者
去看他的方法,build(); doBuild(); init(); configure(); performBuild();
- 看到
配置器
去看他的方法,init(); config();
從寫MySecurityConfig
時使用的@EnableWebSecurity
註解開始看源碼:
@EnableWebSecurity
註解導入了三個類,重點關注WebSecurityConfiguration
我們後面依次分析:
WebSecurityConfiguration
中需要關注兩個方法
-
setFilterChainProxySecurityConfigurer()
方法創建了
WebSecurity
建造者對象,用於後面建造FilterChainProxy
過濾器 -
springSecurityFilterChain()
方法調用
WebSecurity.build()
,建造出FilterChainProxy
過濾器對象
《深入淺出Spring Security(一):三句話解釋框架原理》
《深入淺出Spring Security(二):FilterChainProxy的創建過程》
《深入淺出Spring Security(三):FilterChainProxy的運行過程》