WebSecurityConfiguration的重点是通过WebSecurity创建FilterChainProxy
- • 先分析内部的方法
1、elegatingApplicationListener
- • 看名字就能看出来注册了一个委托类型的监听器
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
......
@Bean
public static DelegatingApplicationListener delegatingApplicationListener() {
return new DelegatingApplicationListener();
}
......
}
- • 内部其实就是一个很简单的把监听器又嵌套了一层,在内部for循环发送事件,所以说重点就是如何注册内部的监听器的
public final class DelegatingApplicationListener implements
ApplicationListener<ApplicationEvent> {
private List<SmartApplicationListener> listeners = new CopyOnWriteArrayList<>();
public void onApplicationEvent(ApplicationEvent event) {
if (event == null) {
return;
}
for (SmartApplicationListener listener : listeners) {
Object source = event.getSource();
if (source != null && listener.supportsEventType(event.getClass())
&& listener.supportsSourceType(source.getClass())) {
listener.onApplicationEvent(event);
}
}
}
/**
* Adds a new SmartApplicationListener to use.
*
* @param smartApplicationListener the SmartApplicationListener to use. Cannot be
* null.
*/
public void addListener(SmartApplicationListener smartApplicationListener) {
Assert.notNull(smartApplicationListener,
"smartApplicationListener cannot be null");
listeners.add(smartApplicationListener);
}
}
- • Debug就会发现默认只有SessionManagementConfigurer会注册一个SessionRegistryImpl
- • SessionRegistryImpl是针对SpringSecurity内部维护的SessionInformation的操作 比如说用户登录后,才会创建会话session,那么通常会有一个SpringSecurity的SessionInformation的创建
2、setFilterChainProxySecurityConfigurer
- • 重点就是创建了WebSecurity,并注册对应的配置类
- • 是创建FilterChainProxy的核心类
@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));
if (this.debugEnabled != null) {
this.webSecurity.debug(this.debugEnabled);
}
//先对配置类进行排序
webSecurityConfigurers.sort(AnnotationAwareOrderComparator.INSTANCE);
Integer previousOrder = null;
Object previousConfig = null;
//这个for循环的意思是:配置类可以通过@Order进行排序,但是如果@Order中的value值相同就表示无法进行排序,就直接抛出异常
for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) {
Integer order = AnnotationAwareOrderComparator.lookupOrder(config);
if (previousOrder != null && previousOrder.equals(order)) {
throw new IllegalStateException("@Order on WebSecurityConfigurers must be unique. Order of " + order
+ " was already used on " + previousConfig + ", so it cannot be used on " + config + " too.");
}
previousOrder = order;
previousConfig = config;
}
for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
this.webSecurity.apply(webSecurityConfigurer);
}
this.webSecurityConfigurers = webSecurityConfigurers;
}
- • 入参有两个重要的类
2.1 ObjectPostProcessor
- • ObjectPostProcessor
- • SecurityConfigurer
- • 首先这个类有一个重要的实现AutowireBeanFactoryObjectPostProcessor,默认注册到容器的也是这个类
- • Spring Security会通过new创建很多bean, 为了让这些由SpringSecurity创建的bean也和跟spring容器中的bean有同样的生命周期,所以出现了此类
final class AutowireBeanFactoryObjectPostProcessor
implements ObjectPostProcessor<Object>, DisposableBean, SmartInitializingSingleton {
private final Log logger = LogFactory.getLog(getClass());
private final AutowireCapableBeanFactory autowireBeanFactory;
private final List<DisposableBean> disposableBeans = new ArrayList<>();
private final List<SmartInitializingSingleton> smartSingletons = new ArrayList<>();
AutowireBeanFactoryObjectPostProcessor(AutowireCapableBeanFactory autowireBeanFactory) {
Assert.notNull(autowireBeanFactory, "autowireBeanFactory cannot be null");
this.autowireBeanFactory = autowireBeanFactory;
}
/**
* 让这些由SpringSecurity创建的bean也和跟spring容器中的bean有同样的生命周期,也能注入相应的依赖,从而进入准备好被使用的状态
* @param object the object to initialize
* @param <T>
* @return
@Override
@SuppressWarnings("unchecked")
public <T> T postProcess(T object) {
if (object == null) {
return null;
}
T result = null;
try {
//进行初始化
result = (T) this.autowireBeanFactory.initializeBean(object, object.toString());
}
catch (RuntimeException ex) {
Class<?> type = object.getClass();
throw new RuntimeException("Could not postProcess " + object + " of type " + type, ex);
}
//进行自动装配属性
this.autowireBeanFactory.autowireBean(object);
if (result instanceof DisposableBean) {
this.disposableBeans.add((DisposableBean) result);
}
if (result instanceof SmartInitializingSingleton) {
this.smartSingletons.add((SmartInitializingSingleton) result);
}
return result;
}
@Override
public void afterSingletonsInstantiated() {
for (SmartInitializingSingleton singleton : this.smartSingletons) {
singleton.afterSingletonsInstantiated();
}
}
@Override
public void destroy() {
for (DisposableBean disposable : this.disposableBeans) {
try {
disposable.destroy();
}
catch (Exception ex) {
this.logger.error(ex);
}
}
}
}
2.2 SecurityConfigurer
- • SpringSecurity在创建对应的过滤器的时候是通过建造者模式进行创建的,SecurityConfigurer算是比较顶级的一个类了,较为完整的构建流程如下:
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
extends AbstractSecurityBuilder<O> {
......
@Override
protected final O doBuild() throws Exception {
synchronized (this.configurers) {
this.buildState = BuildState.INITIALIZING;
beforeInit();
init();
this.buildState = BuildState.CONFIGURING;
beforeConfigure();
configure();
this.buildState = BuildState.BUILDING;
O result = performBuild();
this.buildState = BuildState.BUILT;
return result;
}
......
- • 完整的走完了beforeInit、init、beforeConfigure、configure、performBuild,也映射出了建造者模式下的构建状态
private enum BuildState {
/**
* 表明当前构建器还未进行构建
*/
UNBUILT(0),
/**
* 表明当前构建器正在执行初始化方法,具体规则在doBuild()方法中,下同
*/
INITIALIZING(1),
/**
* 表明当前构建器执行完初始化方法
*/
CONFIGURING(2),
/**
* 表明当前构建器已经执行完配置方法
*/
BUILDING(3),
/**
* 表明当前构建器已经执行完构建方法
*/
BUILT(4);
}
3、autowiredWebSecurityConfigurersIgnoreParents
- • 作用是获取容器中的WebSecurityConfigurer
- • WebSecurityConfigurer的实现类WebSecurityConfigurerAdapter是配置Spring Security过滤器的实现类
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
extends AbstractSecurityBuilder<O> {
......
@Bean
public static AutowiredWebSecurityConfigurersIgnoreParents autowiredWebSecurityConfigurersIgnoreParents(
ConfigurableListableBeanFactory beanFactory) {
return new AutowiredWebSecurityConfigurersIgnoreParents(beanFactory);
}
......
4、setImportMetadata
- • 本质上就是获取在@EnableWebSecurity中设置的是否开启debug日志打印
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
extends AbstractSecurityBuilder<O> {
......
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
//默认只有WebSecurityEnablerConfiguration导入了此类,而此类一定标志了@EnableWebSecurity
Map<String, Object> enableWebSecurityAttrMap = importMetadata
.getAnnotationAttributes(EnableWebSecurity.class.getName());
AnnotationAttributes enableWebSecurityAttrs = AnnotationAttributes.fromMap(enableWebSecurityAttrMap);
this.debugEnabled = enableWebSecurityAttrs.getBoolean("debug");
if (this.webSecurity != null) {
this.webSecurity.debug(this.debugEnabled);
}
}
......
5、springSecurityFilterChain
- • 往容器中注册过滤器,是构建过滤器的入口,也就是注册FilterChainProxy
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
extends AbstractSecurityBuilder<O> {
......
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
boolean hasConfigurers = webSecurityConfigurers != null
&& !webSecurityConfigurers.isEmpty();
// 当配置类和过滤器链都没有的时候注册一个配置类
if (!hasConfigurers) {
WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
.postProcess(new WebSecurityConfigurerAdapter() {
});
webSecurity.apply(adapter);
}
return webSecurity.build();
}
......
- • 第六行代码会判断是否有配置类的存在,即使我们没有注册WebSecurityConfigurer的配置类,也依旧会有一个DefaultConfigurerAdapter注册到容器中
- •
graph TD
SecurityAutoConfiguration --> SpringBootWebSecurityConfiguration --> DefaultConfigurerAdapter