在springboot中使用 spring security 通常会 创建一个 SecurityConfig类
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
}
注意 @EnableWebSecurity 注解 ,该注解做了很多事情
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({WebSecurityConfiguration.class, ObjectPostProcessorConfiguration.class, SpringWebMvcImportSelector.class})
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
boolean debug() default false;
}
EnableWebSecurity类 Import WebSecurityConfiguration、ObjectPostProcessorConfiguration和SpringWebMvcImportSelector类
分别看看这三个类的作用
WebSecurityConfiguration类有这么一个方法springSecurityFilterChain()
代码如下:
@Bean(
name = {"springSecurityFilterChain"}
)
public Filter springSecurityFilterChain() throws Exception {
boolean hasConfigurers = this.webSecurityConfigurers != null && !this.webSecurityConfigurers.isEmpty();
if(!hasConfigurers) {
WebSecurityConfigurerAdapter adapter = (WebSecurityConfigurerAdapter)this.objectObjectPostProcessor.postProcess(new WebSecurityConfigurerAdapter() {
});
this.webSecurity.apply(adapter);
}
return (Filter)this.webSecurity.build();
}
初试化了springSecurityFilterChain bean,这个chain就是springSecurity中核心的过滤器链
从代码中可以看到调用了 webSecurity.build()方法
webSecurity什么时候注入的?
public final O build() throws Exception {
if(this.building.compareAndSet(false, true)) {
this.object = this.doBuild();
return this.object;
} else {
throw new AlreadyBuiltException("This object has already been built");
}
}
此方法其实是AbstractSecurityBuilder抽象类的方法,调用了this.doBuild()
protected final O doBuild() throws Exception {
LinkedHashMap var1 = this.configurers;
synchronized(this.configurers) {
this.buildState = AbstractConfiguredSecurityBuilder.BuildState.INITIALIZING;
this.beforeInit();
this.init();
this.buildState = AbstractConfiguredSecurityBuilder.BuildState.CONFIGURING;
this.beforeConfigure();
this.configure();
this.buildState = AbstractConfiguredSecurityBuilder.BuildState.BUILDING;
Object result = this.performBuild();
this.buildState = AbstractConfiguredSecurityBuilder.BuildState.BUILT;
return result;
}
}
doBuild()方法核心就是调用了 this.performBuild()
protected Filter performBuild() throws Exception {
Assert.state(!this.securityFilterChainBuilders.isEmpty(), "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. Typically this done 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();
ArrayList securityFilterChains = new ArrayList(chainSize);
Iterator filterChainProxy = this.ignoredRequests.iterator();
while(filterChainProxy.hasNext()) {
RequestMatcher result = (RequestMatcher)filterChainProxy.next();
securityFilterChains.add(new DefaultSecurityFilterChain(result, new Filter[0]));
}
filterChainProxy = this.securityFilterChainBuilders.iterator();
while(filterChainProxy.hasNext()) {
SecurityBuilder result1 = (SecurityBuilder)filterChainProxy.next();
securityFilterChains.add(result1.build());
}
FilterChainProxy filterChainProxy1 = new FilterChainProxy(securityFilterChains);
if(this.httpFirewall != null) {
filterChainProxy1.setFirewall(this.httpFirewall);
}
filterChainProxy1.afterPropertiesSet();
Object result2 = filterChainProxy1;
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");
result2 = new DebugFilter(filterChainProxy1);
}
this.postBuildAction.run();
return (Filter)result2;
}
performBuild()实际上还是调用了WebSecurity的performBuild()方法
还添加了@EnableGlobalAuthentication