前言
之前在配置SpringSecurity
整合Oauth2的时候发现了默认配置的请求配置是无效的,因此怀疑SpringSecurity
会根据不同的url配置不同的过滤链。因此在代码中打断点观察Spring的启动流程。
1. SpringSecurity的基本组件
SecurityConfigurer
// 0. 可以看见这个类有两个参数B 和 O , 其中 就是将参数B 最后生成参数C, B是C的Builder(构造器)
// 1. init和 configure 方法就是尽可能的封装builder来完善最后生成的O, 目前我们熟悉的SecurityConfigurer 有 WebSecurityConfigurerAdapter,他的builder是 WebSecurity,O是 Filter
// 2. WebSecurity 是 SpringSecurity 的核心,他在Spirng容器中是唯一的。 为此介绍一下 WebSecurity
public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
void init(B builder) throws Exception;
void configure(B builder) throws Exception;
}
WebSecurityConfigurerAdapter (他是一个SecurityConfigurer, 他是用来封装 WebSecurity(Builder的)
因此如上代码可以看成以下片段
// 0. 这段代码来自于我们熟悉的`WebSecurityConfigurerAdapter`,我们通常继承他来进行配置权限之类的
public void init(final WebSecurity web) throws Exception {
// 1. 这段代码是生成一个 HttpSecurity , 这是我们熟悉的对象。
final HttpSecurity http = getHttp();
// 2. 这段代码非常重要,其中就是将我们的 配置好的 HttpSecurity 添加到 WebSecurity中, 因此我们隐隐猜到,一个spirng中不会仅仅只有一条过滤链。我们自己配置的 HttpSecurity 知识其中的一一环
// 3. 这里同时又有个问题,既然 HttpSecurity 是多例的,为什么要将他的独有的参数放到 WebSecurity中。比如 postBuildActiong() 和
// web.securityInterceptor(securityInterceptor); 这里先不管。
web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() {
public void run() {
FilterSecurityInterceptor securityInterceptor = http
.getSharedObject(FilterSecurityInterceptor.class);
web.securityInterceptor(securityInterceptor);
}
});
}
public void configure(WebSecurity web) throws Exception {
}
WebSecurity (他是一个Builder【SecurityBuilder<Filter>】)
他有SecurityConfigurer来加强这个Builder, 例如WebSecurityConfigurerAdapter
HttpSecurity (他是一个Builder【SecurityBuilder<DefaultSecurityFilterChain>】)
他并没有一个 SecurityConfigurer 来加强这个Builder, 我们对他配置的方法protected void configure(HttpSecurity http)
是来源于WebSecurityConfigurerAdapter中的方法,如果我们不重写他默认的http生成如下
protected void configure(HttpSecurity http) throws Exception {
logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).")