前言
总结创建WebSecuirty的创建过程,及其构建过程。有和前面重复的地方,不管了…
1. 用户自定义的配置类
@EnableWebSecurity
@ComponentScan("fn.wd.security")
public class SpringSecurityConfiger extends WebSecurityConfigurerAdapter {
...
}
2. @EnableWebSecurity
@Import({ WebSecurityConfiguration.class, ObjectPostProcessorConfiguration.class,
SpringWebMvcImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
...
}
3. WebSecurityConfiguration中创建WebSecurity
@Autowired(required = false)
public void setFilterChainProxySecurityConfigurer(
//参数一:注入被@EnableWebSecurity注入导入的后置处理器
ObjectPostProcessor<Object> objectPostProcessor,
//参数二:注入spring web容器中所有的WebSecurityConfigurer
List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers) {
//1.创建WebSecurity,传递objectPostProcessor,是为了当这个构建器构建对象完成后,可以给这个对象进行后置处理
//2.后置处理WebSecurity
//3.PS:后置处理的功能是:使容器外的对象享受像spring容器内的bean一样的待遇
webSecurity = objectPostProcessor
.postProcess(new WebSecurity(objectPostProcessor));
if (debugEnabled != null) {
webSecurity.debug(debugEnabled);
}
//将配置WebSecurity的配置器排序,这里通常就是我们自定义的那个SecurityConfigurerAdapter
Collections.sort(webSecurityConfigurers, AnnotationAwareOrderComparator.INSTANCE);
//如果有多个配置器,配置顺序不能是一样的,否则通不过
Integer previousOrder = null;
Object previousConfig = null;
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;
}
//让我们自定义的SecurityConfigurerAdapter,应用到new出来的这个WebSecurity
for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
webSecurity.apply(webSecurityConfigurer);
}
//将用到的配置器放到属性中,以提示:已经对WebSecurity进行配置了
this.webSecurityConfigurers = webSecurityConfigurers;
}
可以看到,webSecurityConfigurers中就是我们自定义的那一个:
4. WebSecurityConfiguration中触发WebSecurity的构建过程
//构建的bean的名字叫做:springSecurityFilterChain
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
//看webSecurityConfigurers是不是空,以判断是否对WebSecurity进行了配置
boolean hasConfigurers = webSecurityConfigurers != null
&& !webSecurityConfigurers.isEmpty();
//如果没有配置(即:用户没有自定义WebSecurityConfigurerAdapter),那么框架会给一个空实现,所有配置功能都使用WebSecurityConfigurerAdapter中默认的
if (!hasConfigurers) {
WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
.postProcess(new WebSecurityConfigurerAdapter() {
});
webSecurity.apply(adapter);
}
//触发FilterChainProxy的构建过程
return webSecurity.build();
}
5.AbstractConfiguredSecurityBuilder定义构建模版
AbstractConfiguredSecurityBuilder是WebSecurity的父类,定义了doBuild()方法的执行模版。
//build()->doBuild();做了些什么呢?前文有提到过哦~
protected final O doBuild() throws Exception {
//针对WebSecurity.这里的configurers指的就是我们自定义的那个WebSecurityConfigurer
synchronized (configurers) {
buildState = BuildState.INITIALIZING;
beforeInit();
//init()前面也说过,迭代所有的configurer,调用它们的init(builder)
init();
buildState = BuildState.CONFIGURING;
beforeConfigure();
//configure()前面也说过,迭代所有的configurer,调用它们的configure(builder)
configure();
buildState = BuildState.BUILDING;
//performBuild()需要子类实现,WebSecurity中是怎么实现的呢?
O result = performBuild();
buildState = BuildState.BUILT;
return result;
}
}
WebSecurityConfigurerAdapter完成模版方法中的init()
这里触发了HttpSecurity的创建(后面详细讨论),并将其设置到WebSecurity中。
public void init(final WebSecurity web) throws Exception {
final HttpSecurity http = getHttp();
//将HttpSecurity添加到WebSecurity的securityFilterChainBuilders属性中
web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() {
public void run() {
FilterSecurityInterceptor securityInterceptor = http
.getSharedObject(FilterSecurityInterceptor.class);
web.securityInterceptor(securityInterceptor);
}
});
}
SpringSecurityConfiger完成模版方法中的configurer()
注意:这个类并不是框架的,是需要用户自定义实现的。WebSecurityConfigurerAdapter中configurer()是空实现的,由子类(用户自定义的)去完成实现。一个例子:
@EnableWebSecurity
@ComponentScan("fn.wd.security")
public class SpringSecurityConfiger extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
/*
* web.ignoring()返回的是ignoredRequestRegistry,最终将忽略的请求
* 添加到WebSecurity中的ignoredRequests属性中。
*/
web.ignoring().antMatchers("/static/**");
web.ignoring().antMatchers("/favicon.ico");
web.ignoring().antMatchers("/resources/**");
}
}
它的功能还记得吗?前文有提到哦~~
WebSecurity完成模版方法中的performBuild()
有关异常和校验等的代码被我删掉了,只保留了核心的,请自行查看源码。
@Override
protected Filter performBuild() throws Exception {
//ignoredRequests.size():是获取忽略的请求个数
//securityFilterChainBuilders.size():是获取“过滤器链的配置器”的个数
int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
//链,集合
List<SecurityFilterChain> securityFilterChains
= new ArrayList<SecurityFilterChain>(chainSize);
//给需要忽略的请求分别创建没有一个过滤器的链
for (RequestMatcher ignoredRequest : ignoredRequests) {
securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
}
//使用“过滤器链的配置器”创建过滤器链
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
//触发了HttpSecurity的构建过程(后面详细讨论)
securityFilterChains.add(securityFilterChainBuilder.build());
}
//创建过滤器链的代理,将所有的过滤器链都封装进去
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
if (httpFirewall != null) {
filterChainProxy.setFirewall(httpFirewall);
}
filterChainProxy.afterPropertiesSet();
Filter result = filterChainProxy;
postBuildAction.run();
//返回这个过滤器链的代理
return result;
}