使用WebSecurity创建了FilterChainProxy拦截的链路代理类,对请求进行拦截。可以通过继承WebSecurityConfigurerAdapter对其进行任意的配置
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
//判断是否有WebSecurityConfigurer的实现类。
//如果没有,则创建默认的WebSecurityConfigurerAdapter
boolean hasConfigurers = webSecurityConfigurers != null
&& !webSecurityConfigurers.isEmpty();
if (!hasConfigurers) {
WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
.postProcess(new WebSecurityConfigurerAdapter() {
});
webSecurity.apply(adapter);
}
return webSecurity.build();
}
这里着重看下springSecurityFilterChain()这个方法,webSecurityConfigurers集合是获取了WebSecurityConfigurer的实现类,而WebSecurityConfigurerAdapter实现了该接口,所以我们只需要继承WebSecurityConfigurerAdapter 该方法会通过WebSecurity构建出一个FilterChainProxy,也是spring security拦截器的核心入口。
首先看下WebSecurity的类结构图
WebSecurity.build():
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");
}
查看源码发现,build()内部是调用了doBuild()方法
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;
}
}
大致可以分为7步骤
1、修改构建状态为构建中
2、初始化前 beforeInit()。该方法内是空的,如果在初始化前需要什么操作可以重写此方法
3、初始化 init()。这里是调用了SecurityConfigurer实现类的init()方法。WebSecurityConfigurerAdapter实现了该接口。获取HttpSecurity以及设置WebSecurity的拦截器FilterSecurityInterceptor
protected final HttpSecurity getHttp() throws Exception {
if (http != null) {
return http;
}
DefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor
.postProcess(new DefaultAuthenticationEventPublisher());
//1、设置认证事件发布器
localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);
//2、获取AuthenticationManager对象作为authenticationBuilder的父级
AuthenticationManager authenticationManager = authenticationManager();
authenticationBuilder.parentAuthenticationManager(authenticationManager);
//3、设置authenticationBuilder的认证事件发布器
authenticationBuilder.authenticationEventPublisher(eventPublisher);
//4、创建Map类型分享对象
Map<Class<?>, Object> sharedObjects = createSharedObjects();
//5、创建HttpSecurity,可以配置基于web的安全性请求
http = new HttpSecurity(objectPostProcessor, authenticationBuilder,
sharedObjects);
//6、是否禁用默认配置,如果为false,则配置默认的http设置
if (!disableDefaults) {
// @formatter:off
http
.csrf().and() //跨域请求伪造验证
.addFilter(new WebAsyncManagerIntegrationFilter())
.exceptionHandling().and() //异常执行器,会创建ExceptionTranslationFilter
.headers().and() //HeaderWriterFilter
.sessionManagement().and() //SessionManagementFilter
.securityContext().and() //SecurityContextPersistenceFilter
.requestCache().and() //RequestCacheAwareFilter
.anonymous().and() //AnonymousAuthenticationFilter
.servletApi().and() //SecurityContextHolderAwareRequestFilter
.apply(new DefaultLoginPageConfigurer<>()).and() //DefaultLoginPageGeneratingFilter
.logout(); //LogoutFilter
// @formatter:on
ClassLoader classLoader = this.context.getClassLoader();
//7、从配置文件中加载AbstractHttpConfigurer
List<AbstractHttpConfigurer> defaultHttpConfigurers =
SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);
for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
http.apply(configurer);
}
}
//8、调用configure(HttpSecurity),子类可以重写该方法对http进行配置
configure(http);
return http;
}
4、配置前。 默认空
5、配置。调用SecurityConfigurer的configure(WebSecurity)
6、构建FilterChainProxy
7、修改构建状态为已构建