原理解析
前置知识
SecurityBuilder<O>【构建者】
Spring Security 用【构建者】来构建【目标对象】
package org.springframework.security.config.annotation;
public interface SecurityBuilder<O> {
O build() throws Exception;
}
AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>【可配置的构建者】
实现了【构建者】接口
【可配置的构建者】持有多个 SecurityConfigurer<O, B>【配置器】
通过定义【配置器】对象来影响构建过程,从而达到配置【目标对象】的效果
AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>> 继承了 AbstractSecurityBuilder<O>
AbstractSecurityBuilder 用于限制:一个【构建者】对象只能被用来构建一次,否则抛异常
package org.springframework.security.config.annotation;
public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> {
private AtomicBoolean building = new AtomicBoolean();
private O object;
@Override
public final O build() throws Exception {
if (this.building.compareAndSet(false, true)) {
this.object = doBuild();
return this.object;
}
throw new AlreadyBuiltException("This object has already been built");
}
...
}
配置逻辑
Spring Security 的功能由 FilterChainProxy 完成
一个 FilterChainProxy 对应多个 SecurityFilterChain
一个经过 FilterChainProxy 的请求最多只会匹配到其中一个 SecurityFilterChain(有可能一个也匹配不到)
一个 SecurityFilterChain 对应多个 Filter
一个 SecurityFilterChain 对应一个 AuthenticationManager
一个 AuthenticationManager 对应多个 AuthenticationProvider
配置 Spring Security 就是构建 FilterChainProxy
- 为 FilterChainProxy 构建多个 SecurityFilterChain
- 为每个 SecurityFilterChain 添加多个 Filter
- 为每个 SecurityFilterChain 构建一个 AuthenticationManager
- 为每个 AuthenticationManager 添加多个 AuthenticationProvider
涉及的【可配置构建器】
- WebSecurity(AbstractConfiguredSecurityBuilder<Filter, WebSecurity>)
用于构建 FilterChainProxy- 实例字段 configurers(多个 SecurityConfigurer<Filter, WebSecurity>)
- WebSecurityConfigurerAdapter(SecurityConfigurer<Filter, WebSecurity>)
- 实例字段 http(HttpSecurity)
- 实例字段 authenticationBuilder(AuthenticationManagerBuilder)
- WebSecurityConfigurerAdapter(SecurityConfigurer<Filter, WebSecurity>)
- 实例字段 configurers(多个 SecurityConfigurer<Filter, WebSecurity>)
- HttpSecurity(AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>)
用于构建 SecurityFilterChain- 实例字段 AbstractConfiguredSecurityBuilder.sharedObjects(一个 Map<Class<?>, Object>)
其中的 AuthenticationManagerBuilder 就是 WebSecurityConfigurerAdapter.authenticationBuilder - 实例字段 configurers
- OAuth2ClientConfigurer<HttpSecurity>(SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>)
- 实例字段 AbstractConfiguredSecurityBuilder.sharedObjects(一个 Map<Class<?>, Object>)
- AuthenticationManagerBuilder(AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>)
用于构建 AuthenticationManager
其中:
- WebSecurity.configurers
由 @Autowired WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(…)
参数注入:@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}")
其中包括自定义的 WebSecurityConfigurerAdapter 对象 - WebSecurityConfigurerAdapter.authenticationBuilder
由 @Autowired WebSecurityConfigurerAdapter.setApplicationContext(ApplicationContext context)
创建对象:this.authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor,
passwordEncoder)
客户端程序员可以通过 MySecurityConfigurer extends WebSecurityConfigurerAdapter 来配置 FilterChainProxy
注意:MySecurityConfigurer 必须是 Spring 容器中的 Bean
否则不会加入到 WebSecurity.configurers 中
用到的设计模式
- 模板方法
AbstractSecurityBuilder 的 build() 防止重复构建
实际调用的是 AbstractConfiguredSecurityBuilder.doBuild()
而 doBuild() 有多个固定逻辑:init()、configure()、performBuild()
其中 performBuild() 为抽象方法,由对应构建者重写(如:WebSecurity.performBuild()、HttpSecurity.performBuild()) - 构建者
- WebSecurity(AbstractConfiguredSecurityBuilder<Filter, WebSecurity>)
构建 FilterChainProxy - HttpSecurity(AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>)
构建 SecurityFilterChain - AuthenticationManagerBuilder(AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>)
构建 AuthenticationManager
- WebSecurity(AbstractConfiguredSecurityBuilder<Filter, WebSecurity>)
- 状态机
AbstractConfiguredSecurityBuilder.doBuild() 中有多个状态的设置操作
private BuildState buildState = BuildState.UNBUILT;
配置过程
所有的配置过程,都是在 Spring 装配 Bean 阶段完成的
一、提前装配的 Bean
MySecurityConfig 对象(SecurityConfigurer<Filter, WebSecurity>)
有 @Component 注解,Spring 容器会创建该对象
之后会被加入 WebSecurity.configurers
@Component
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
...
}
AuthenticationManagerBuilder 对象(AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>)
WebSecurityConfigurerAdapter.setApplicationContext() 方法中直接 new 出来
赋值给:WebSecurityConfigurerAdapter.authenticationBuilder
package org.springframework.security.config.annotation.web.configuration;
public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> {
...
private AuthenticationManagerBuilder authenticationBuilder;
...
@Autowired
public void setApplicationContext(ApplicationContext context) {
...
this.authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor,
passwordEncoder);
...
}
...
}
WebSecurity 对象(AbstractConfiguredSecurityBuilder<Filter, WebSecurity>)
WebSecurityConfiguration.setFilterChainProxySecurityConfigurer() 方法中直接被 new 出来
上边的 MySecurityConfig 对象会在这个方法中被加入到 WebSecurity.configurers
package org.springframework.security.config.annotation.web.configuration;
@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
private WebSecurity webSecurity;
...
// 设置 webSecurity
@Autowired(required = false)
public void setFilterChainProxySecurityConfigurer(ObjectPostProcessor<Object> objectPostProcessor,
@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
throws Exception {
this.webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));
...
for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
this.webSecurity.apply(webSecurityConfigurer);
}
this.webSecurityConfigurers = webSecurityConfigurers;
}
}
二、开始构建
只要引入了 Spring Security 包,类路径下就会有 WebSecurityConfiguration
package org.springframework.security.config.annotation.web.configuration;
@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration
implements ImportAware, BeanClassLoaderAware {
private WebSecurity webSecurity;
...
// 构建 FilterChainProxy
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
...
return this.webSecurity.build(); //(1-35)
}
...
}
WebSecurity
package org.springframework.security.config.annotation.web.builders;
public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter, WebSecurity>
implements SecurityBuilder<Filter>, ApplicationContextAware {
...
private final List<SecurityBuilder<? extends SecurityFilterChain>> securityFilterChainBuilders = new ArrayList<>();
...
public WebSecurity addSecurityFilterChainBuilder(
SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder) { // -->(19) // 201
this.securityFilterChainBuilders.add(securityFilterChainBuilder);
return this;
}
...
@Override
protected Filter performBuild() throws Exception { // -->(22-35) // 272
Assert.state(!this.securityFilterChainBuilders.isEmpty(),
() -> "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. "
+ "Typically this is done by exposing a SecurityFilterChain bean "
+ "or by adding a @Configuration that extends WebSecurityConfigurerAdapter. "
+ "More advanced users can invoke " + WebSecurity.class.getSimpleName()
+ ".addSecurityFilterChainBuilder directly");
int chainSize = this.ignoredRequests.size() + this.securityFilterChainBuilders.size();
List<SecurityFilterChain> securityFilterChains = new ArrayList<>(chainSize);
for (RequestMatcher ignoredRequest : this.ignoredRequests) {
securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
}
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : this.securityFilterChainBuilders) {
// HttpSecurity.build() 构建 SecurityFilterChain,并加入 FilterChainProxy.filterChains
securityFilterChains.add(securityFilterChainBuilder.build()); //(23-35)
}
// new 了一个 FilterChainProxy 对象,并注入 FilterChainProxy.filterChains
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
if (this.httpFirewall != null) {
filterChainProxy.setFirewall(this.httpFirewall);
}
if (this.requestRejectedHandler != null) {
filterChainProxy.setRequestRejectedHandler(this.requestRejectedHandler);
}
filterChainProxy.afterPropertiesSet();
Filter result = filterChainProxy;
if (this.debugEnabled) {
this.logger.warn("\n\n" + "********************************************************************\n"
+ "********** Security debugging is enabled. *************\n"
+ "********** This may include sensitive information. *************\n"
+ "********** Do not use in a production system! *************\n"
+ "********************************************************************\n\n");
result = new DebugFilter(filterChainProxy);
}
this.postBuildAction.run();
return result;
}
...
}
AbstractConfiguredSecurityBuilder<Filter, WebSecurity>
package org.springframework.security.config.annotation;
public abstract class AbstractConfiguredSecurityBuilder<Filter, WebSecurity>
extends AbstractSecurityBuilder<Filter> {
...
private final LinkedHashMap<Class<? extends SecurityConfigurer<Filter, WebSecurity>>, List<SecurityConfigurer<Filter, WebSecurity>>>
configurers = new LinkedHashMap<>();
...
@Override
protected final Filter doBuild() throws Exception { // -->(2-35) // 296
synchronized (this.configurers) {
this.buildState = BuildState.INITIALIZING;
beforeInit();
// 循环调用 configurers 的 init() 方法
init(); //(3-19)
this.buildState = BuildState.CONFIGURING;
beforeConfigure();
// 循环调用 configurers 的 configure() 方法
configure(); //(20-21)
this.buildState = BuildState.BUILDING;
// WebSecurity.performBuild()
Filter result = performBuild(); //(22-35)
this.buildState = BuildState.BUILT;
return result;
}
}
...
private void init() throws Exception { // -->(3-19) // 335
Collection<SecurityConfigurer<Filter, WebSecurity>> configurers = getConfigurers();
for (SecurityConfigurer<Filter, WebSecurity> configurer : configurers) {
configurer.init((WebSecurity) this); //(4-19)
}
for (SecurityConfigurer<Filter, WebSecurity> configurer : this.configurersAddedInInitializing) {
configurer.init((WebSecurity) this);
}
}
private void configure() throws Exception { // -->(20-21) // 346
Collection<SecurityConfigurer<Filter, WebSecurity>> configurers = getConfigurers();
for (SecurityConfigurer<Filter, WebSecurity> configurer : configurers) {
// MySecurityConfig.configure(WebSecurity web)
configurer.configure((WebSecurity) this); //(21)
}
}
private Collection<SecurityConfigurer<Filter, WebSecurity>> getConfigurers() {
List<SecurityConfigurer<Filter, WebSecurity>> result = new ArrayList<>();
for (List<SecurityConfigurer<Filter, WebSecurity>> configs : this.configurers.values()) {
result.addAll(configs);
}
return result;
}
...
}
AbstractSecurityBuilder
package org.springframework.security.config.annotation;
public abstract class AbstractSecurityBuilder<Filter> implements SecurityBuilder<Filter> {
private AtomicBoolean building = new AtomicBoolean();
private Filter object;
@Override
public final Filter build() throws Exception { // -->(1-35)
// 防止重复构建
if (this.building.compareAndSet(false, true)) {
this.object = doBuild(); //(2-35)
return this.object;
}
throw new AlreadyBuiltException("This object has already been built");
}
...
protected abstract Filter doBuild() throws Exception;
}
WebSecurityConfigurerAdapter
package org.springframework.security.config.annotation.web.configuration;
@Order(100)
public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> {
...
private AuthenticationConfiguration authenticationConfiguration;
// 用于构建 SecurityFilterChain 的 AuthenticationManager
private AuthenticationManagerBuilder authenticationBuilder;
private AuthenticationManagerBuilder localConfigureAuthenticationBldr;
private boolean disableLocalConfigureAuthenticationBldr;
private boolean authenticationManagerInitialized;
// SecurityFilterChain 的 AuthenticationManager 的父 AuthenticationManager
private AuthenticationManager authenticationManager;
...
private HttpSecurity http;
...
/*
可重写,用于配置 this.localConfigureAuthenticationBldr
如果重写了该方法,this.disableLocalConfigureAuthenticationBldr 不会被设置为 true
SecurityFilterChain 的 AuthenticationManager 的父 AuthenticationManager 会用 this.localConfigureAuthenticationBldr 构建
否则,会使用 this.authenticationConfiguration.getAuthenticationManager() 获取父 AuthenticationManager
即 AuthenticationConfiguration.getAuthenticationManager()
*/
protected void configure(AuthenticationManagerBuilder auth) throws Exception { // -->(7) // 188
this.disableLocalConfigureAuthenticationBldr = true;
}
protected final HttpSecurity getHttp() throws Exception { // -->(5-18) // 198
if (this.http != null) {
return this.http;
}
AuthenticationEventPublisher eventPublisher = getAuthenticationEventPublisher();
this.localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);
// 获取 SecurityFilterChain 的 AuthenticationManager 的父 AuthenticationManager
AuthenticationManager authenticationManager = authenticationManager(); //(6-8)
this.authenticationBuilder.parentAuthenticationManager(authenticationManager); //(9)
Map<Class<?>, Object> sharedObjects = createSharedObjects();
this.http = new HttpSecurity(this.objectPostProcessor, this.authenticationBuilder, sharedObjects); //(10-13)
if (!this.disableDefaults) {
applyDefaultConfiguration(this.http);
ClassLoader classLoader = this.context.getClassLoader();
List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader
.loadFactories(AbstractHttpConfigurer.class, classLoader);
for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
// 将一个默认 configurers 列表加入到 this.http 的 configurers 中
this.http.apply(configurer); //(14)
}
}
/*
这一步用来添加和配置 HttpSecurity.configurers
一个 configurer 对应 SecurityFilterChain 中的若干个 Filter
*/
configure(this.http); //(15-18)
return this.http;
}
...
protected AuthenticationManager authenticationManager() throws Exception { // -->(6-8) // 262
if (!this.authenticationManagerInitialized) {
configure(this.localConfigureAuthenticationBldr); //(7)
if (this.disableLocalConfigureAuthenticationBldr) {
this.authenticationManager = this.authenticationConfiguration.getAuthenticationManager(); //(8)
}
else {
this.authenticationManager = this.localConfigureAuthenticationBldr.build();
}
this.authenticationManagerInitialized = true;
}
return this.authenticationManager;
}
...
@Override
public void init(WebSecurity web) throws Exception { // -->(4-19) // 314
// 创建 HttpSecurity(SecurityBuilder<DefaultSecurityFilterChain>)
HttpSecurity http = getHttp(); //(5-18)
// 把 HttpSecurity 加入 WebSecurity(SecurityBuilder<Filter>)的 securityFilterChainBuilders
web.addSecurityFilterChainBuilder(http).postBuildAction(() -> { //(19)
FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);
web.securityInterceptor(securityInterceptor);
});
}
...
}
AuthenticationConfiguration
package org.springframework.security.config.annotation.authentication.configuration;
@Configuration(proxyBeanMethods = false)
@Import(ObjectPostProcessorConfiguration.class)
public class AuthenticationConfiguration {
...
public AuthenticationManager getAuthenticationManager() throws Exception { // -->(8) // 110
if (this.authenticationManagerInitialized) {
return this.authenticationManager;
}
AuthenticationManagerBuilder authBuilder = this.applicationContext.getBean(AuthenticationManagerBuilder.class);
if (this.buildingAuthenticationManager.getAndSet(true)) {
return new AuthenticationManagerDelegator(authBuilder);
}
for (GlobalAuthenticationConfigurerAdapter config : this.globalAuthConfigurers) {
authBuilder.apply(config);
}
this.authenticationManager = authBuilder.build();
if (this.authenticationManager == null) {
this.authenticationManager = getAuthenticationManagerBean();
}
this.authenticationManagerInitialized = true;
return this.authenticationManager;
}
...
}
HttpSecurity
package org.springframework.security.config.annotation.web.builders;
public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
implements SecurityBuilder<DefaultSecurityFilterChain>, HttpSecurityBuilder<HttpSecurity> {
...
private List<OrderedFilter> filters = new ArrayList<>();
...
public HttpSecurity(ObjectPostProcessor<Object> objectPostProcessor,
AuthenticationManagerBuilder authenticationBuilder, Map<Class<?>, Object> sharedObjects) { // -->(10-13) // 154
super(objectPostProcessor);
Assert.notNull(authenticationBuilder, "authenticationBuilder cannot be null");
setSharedObject(AuthenticationManagerBuilder.class, authenticationBuilder); //(11-12)
for (Map.Entry<Class<?>, Object> entry : sharedObjects.entrySet()) {
setSharedObject((Class<Object>) entry.getKey(), entry.getValue());
}
ApplicationContext context = (ApplicationContext) sharedObjects.get(ApplicationContext.class);
this.requestMatcherConfigurer = new RequestMatcherConfigurer(context); //(13)
}
...
public HttpSecurity oauth2Client(Customizer<OAuth2ClientConfigurer<HttpSecurity>> oauth2ClientCustomizer)
throws Exception { // -->(16-18) // 2382
/*
getOrApply():
AbstractConfiguredSecurityBuilder.configurers 中有 OAuth2ClientConfigurer<HttpSecurity> 对象则获取
没有则将 new 的 OAuth2ClientConfigurer<HttpSecurity> 对象加入 AbstractConfiguredSecurityBuilder.configurers
oauth2ClientCustomizer 是客户端程序员创建的匿名内部类实现,用来根据需求调用 OAuth2ClientConfigurer<HttpSecurity> 的 API 进行配置
*/
oauth2ClientCustomizer.customize(getOrApply(new OAuth2ClientConfigurer<>())); //(17-18)
return HttpSecurity.this;
}
...
@Override
public <C> void setSharedObject(Class<C> sharedType, C object) { // -->(11-12) // 2608
super.setSharedObject(sharedType, object); //(12)
}
...
@Override
protected DefaultSecurityFilterChain performBuild() { // 2618
this.filters.sort(OrderComparator.INSTANCE);
List<Filter> sortedFilters = new ArrayList<>(this.filters.size());
for (Filter filter : this.filters) {
sortedFilters.add(((OrderedFilter) filter).filter);
}
return new DefaultSecurityFilterChain(this.requestMatcher, sortedFilters);
}
@Override
public HttpSecurity authenticationProvider(AuthenticationProvider authenticationProvider) { // -->(29-32) // 2628
/*
(30-31)从 AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>.sharedObjects 获取 AuthenticationManagerBuilder 对象
就是 WebSecurityConfigurerAdapter.authenticationBuilder
new HttpSecurity() 时加入的 AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>.sharedObjects
(32)将 AuthenticationProvider 加入 AuthenticationManagerBuilder.authenticationProviders
*/
getAuthenticationRegistry() //(30-31)
.authenticationProvider(authenticationProvider); //(32)
return this;
}
...
private AuthenticationManagerBuilder getAuthenticationRegistry() { // -->(30-31) // 2639
return getSharedObject(AuthenticationManagerBuilder.class); //(31)
}
...
private <C extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>> C getOrApply(C configurer)
throws Exception { // -->(17-18) // 2993
C existingConfig = (C) getConfigurer(configurer.getClass()); //(18)
if (existingConfig != null) {
return existingConfig;
}
return apply(configurer);
}
...
}
AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
public abstract class AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
extends AbstractSecurityBuilder<DefaultSecurityFilterChain> {
...
private final LinkedHashMap<Class<? extends SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>>, List<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>>>
configurers = new LinkedHashMap<>();
...
private final Map<Class<?>, Object> sharedObjects = new HashMap<>(); // 62
...
public <C> void setSharedObject(Class<C> sharedType, C object) { // -->(12) // 148
this.sharedObjects.put(sharedType, object);
}
public <C> C getSharedObject(Class<C> sharedType) { // -->(31) // 158
return (C) this.sharedObjects.get(sharedType);
}
...
public <C extends SecurityConfigurer<O, B>> C getConfigurer(Class<C> clazz) { // -->(18) // 234
List<SecurityConfigurer<O, B>> configs = this.configurers.get(clazz);
if (configs == null) {
return null;
}
Assert.state(configs.size() == 1,
() -> "Only one configurer expected for type " + clazz + ", but got " + configs);
return (C) configs.get(0);
}
...
@Override
protected final DefaultSecurityFilterChain doBuild() throws Exception { // -->(24-35) // 296
synchronized (this.configurers) {
this.buildState = BuildState.INITIALIZING;
beforeInit();
// 循环调用 configurers 的 init() 方法
init(); //(25-32)
this.buildState = BuildState.CONFIGURING;
beforeConfigure();
// 循环调用 configurers 的 configure() 方法
configure(); //(33-35)
this.buildState = BuildState.BUILDING;
// HttpSecurity.performBuild()
DefaultSecurityFilterChain result = performBuild();
this.buildState = BuildState.BUILT;
return result;
}
}
...
private void init() throws Exception { // -->(25-32) // 335
Collection<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> configurers = getConfigurers();
for (SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> configurer : configurers) {
/*
OAuth2ClientConfigurer<HttpSecurity>.init(HttpSecurity)
向 AuthenticationManagerBuilder.authenticationProviders 加入:OAuth2AuthorizationCodeAuthenticationProvider
*/
configurer.init((HttpSecurity) this); //(26-32)
}
for (SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> configurer : this.configurersAddedInInitializing) {
configurer.init((HttpSecurity) this);
}
}
private void configure() throws Exception { // -->() // -->(33-35) // 346
Collection<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> configurers = getConfigurers();
for (SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> configurer : configurers) {
/*
OAuth2ClientConfigurer<HttpSecurity>.configure(HttpSecurity)
向 HttpSecurity.filters 加入:
OAuth2AuthorizationRequestRedirectFilter、OAuth2AuthorizationCodeGrantFilter
*/
configurer.configure((HttpSecurity) this); //(34-35)
}
}
private Collection<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> getConfigurers() {
List<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> result = new ArrayList<>();
for (List<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> configs : this.configurers.values()) {
result.addAll(configs);
}
return result;
}
...
}
AbstractSecurityBuilder
package org.springframework.security.config.annotation;
public abstract class AbstractSecurityBuilder<DefaultSecurityFilterChain> implements SecurityBuilder<DefaultSecurityFilterChain> {
private AtomicBoolean building = new AtomicBoolean();
private DefaultSecurityFilterChain object;
@Override
public final DefaultSecurityFilterChain build() throws Exception { // -->(23-35)
// 防止重复构建
if (this.building.compareAndSet(false, true)) {
this.object = doBuild(); //(24-35)
return this.object;
}
throw new AlreadyBuiltException("This object has already been built");
}
...
protected abstract DefaultSecurityFilterChain doBuild() throws Exception;
}
package org.springframework.security.config.annotation.web.configurers.oauth2.client;
public final class OAuth2ClientConfigurer<HttpSecurity>
extends AbstractHttpConfigurer<OAuth2ClientConfigurer<HttpSecurity>, HttpSecurity> {
private AuthorizationCodeGrantConfigurer authorizationCodeGrantConfigurer = new AuthorizationCodeGrantConfigurer();
...
@Override
public void init(HttpSecurity builder) { // -->(26-32) // 156
this.authorizationCodeGrantConfigurer.init(builder); //(27-32)
}
@Override
public void configure(HttpSecurity builder) { // -->(34-35) // 161
this.authorizationCodeGrantConfigurer.configure(builder); //(35)
}
public final class AuthorizationCodeGrantConfigurer { // 168
...
private void init(B builder) { // -->(27-32) // 227
OAuth2AuthorizationCodeAuthenticationProvider
authorizationCodeAuthenticationProvider = new OAuth2AuthorizationCodeAuthenticationProvider(
getAccessTokenResponseClient()); //(28)
builder.authenticationProvider(postProcess(authorizationCodeAuthenticationProvider)); //(29-32)
}
private void configure(HttpSecurity builder) { // -->(35) // 233
OAuth2AuthorizationRequestRedirectFilter
authorizationRequestRedirectFilter = createAuthorizationRequestRedirectFilter(builder);
builder.addFilter(postProcess(authorizationRequestRedirectFilter));
OAuth2AuthorizationCodeGrantFilter
authorizationCodeGrantFilter = createAuthorizationCodeGrantFilter(builder);
builder.addFilter(postProcess(authorizationCodeGrantFilter));
}
...
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> getAccessTokenResponseClient() { // -->(28) // 282
if (this.accessTokenResponseClient != null) {
return this.accessTokenResponseClient;
}
return new DefaultAuthorizationCodeTokenResponseClient();
}
}
...
}
MySecurityConfig
@Component
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception { // -->(15-18)
http.oauth2Client(oAuth2ClientConfigurer -> {}); //(16-18)
}
@Override
public void configure(WebSecurity web) { // -->(21)
/*
在 WebSecurity.ignoredRequestRegistry 上注册要忽略的 URL 模式
匹配上的请求,会被 FilterChainProxy 忽略
*/
web.ignoring().antMatchers("/webjars/**");
}
}