前言:WebSecurity和HttpSecurity本质上都是SecurityBuilder.需要通过SecurityConfigurer来配置。
//摘自AbstractConfiguredSecurityBuilder
protected final O doBuild() throws Exception {
init();
configure();
O result = performBuild();
return result;
}
}
private void init() throws Exception {
for (SecurityConfigurer<O, B> configurer : configurers) {
configurer.init((B) this);
}
}
private void configure() throws Exception {
for (SecurityConfigurer<O, B> configurer : configurers) {
configurer.configure((B) this);
}
}
故事开始!一切都要从WebSecurityConfiguration讲起。
1.该方法把所有的WebSecurityConfigurer,都加到WebSecurity中。
@Autowired(required = false)
public void setFilterChainProxySecurityConfigurer(
ObjectPostProcessor<Object> objectPostProcessor,
List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
throws Exception {
......
for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
webSecurity.apply(webSecurityConfigurer);
}
this.webSecurityConfigurers = webSecurityConfigurers;
}
2.WebSecurity完成使命(生成过滤器),此时会调用WebSecurityConfigure的init()和configure()方法。
public Filter springSecurityFilterChain() throws Exception {
...
return webSecurity.build();
}
好了,现在把目光转移到WebSecurityConfigurerAdapter的init()。
public void init(final WebSecurity web) throws Exception {
final HttpSecurity http = getHttp();
web.addSecurityFilterChainBuilder(http);
}
这个方法很重要。1.生成了HttpSecurity。2.把HttpSecurity和WebSecurity联系到了一起。
我们先来看看HttpSecurity是如何生成的。
protected final HttpSecurity getHttp() throws Exception {
if (http != null) {
return http;
}
...
http = new HttpSecurity(objectPostProcessor, authenticationBuilder,
sharedObjects);
...
configure(http);
return http;
}
调用了WebSecurityConfigurerAdapter.configure(HttpSecurity)方法。注意:WebSecurityConfigurerAdapter还有一个configure(WebSecurity)方法,不要混淆。
再来看看WebSecurity是如何使用HttpSecurity的。
摘自WebSecurity
protected Filter performBuild() throws Exception {
...
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
securityFilterChains.add(securityFilterChainBuilder.build());
}
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
Filter result = filterChainProxy;
return result;
}
可以看到调用了HttpSecurity的build(),此方法又会调用HttpSecurity内的SecurityConfigurer来完成对它的配置。