文章目录

三句话解释框架原理

  1. 整个框架的核心是一个过滤器,这个过滤器名字叫springSecurityFilterChain类型是FilterChainProxy
  2. 核心过滤器里面是过滤器链(列表),过滤器链的每个元素都是一组URL对应一组过滤器
  3. WebSecurity用来创建FilterChainProxy过滤器,
    HttpSecurity用来创建过滤器链的每个元素。

框架接口设计

关注两个东西:建造者配置器

框架的用法就是通过配置器建造者进行配置

框架用法是写一个自定义配置类,继承WebSecurityConfigurerAdapter,重写几个configure()方法

WebSecurityConfigurerAdapter就是Web安全配置器的适配器对象

建造者(Builder)

// 安全建造者
// 顾名思义是一个builder构造器,创建并返回一个类型为O的对象
public interface SecurityBuilder<O> {
    O build() throws Exception;
}

// 抽象安全建造者
public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> {
    private AtomicBoolean building = new AtomicBoolean();
    private O object;

    public final O build() throws Exception {
        // 限定build()只会进行一次!
        if (this.building.compareAndSet(false, true)) {
            this.object = doBuild();
            return this.object;
        }
        throw new AlreadyBuiltException("This object has already been built");
    }

    // 子类需要重写doBuild()方法
    protected abstract O doBuild() throws Exception;
}

// 配置后的抽象安全建造者
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
        extends AbstractSecurityBuilder<O> {

    // 实现了doBuild()方法,遍历configurers进行init()和configure()。
    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;
        }
    }
    // 它的子类HttpSecurity和WebSecurity都实现了它的performBuild()方法!!!
    protected abstract O performBuild() throws Exception;

    // 主要作用是将安全配置器SecurityConfigurer注入到属性configurers中,
    private void configure() throws Exception {
        Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

        for (SecurityConfigurer<O, B> configurer : configurers) {
            configurer.configure((B) this);
        }
    }
}

配置器(Configurer)

// 安全配置器,配置建造者B,B可以建造O
// 初始化(init)SecurityBuilder,且配置(configure)SecurityBuilder
public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
    void init(B builder) throws Exception;
    void configure(B builder) throws Exception;
}


// Web安全配置器,配置建造者T,T可以建造web过滤器
public interface WebSecurityConfigurer<T extends SecurityBuilder<Filter>> 
        extends SecurityConfigurer<Filter, T> {
}

// Web安全配置器的适配器
// 配置建造者WebSecurity,WebSecurity可以建造核心过滤器
public abstract class WebSecurityConfigurerAdapter 
        implements WebSecurityConfigurer<WebSecurity> {
}


// 用于构建FilterChainProxy的建造者
public final class WebSecurity 
    extends AbstractConfiguredSecurityBuilder<Filter, WebSecurity>
    implements
        SecurityBuilder<Filter>, ApplicationContextAware {
}

// 用于构建SecurityFilterChain的建造者
public final class HttpSecurity 
    extends AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
    implements 
        SecurityBuilder<DefaultSecurityFilterChain>,
        HttpSecurityBuilder<HttpSecurity> {

}

总结

  1. 看到建造者去看他的方法,build(); doBuild(); init(); configure(); performBuild();
  2. 看到配置器去看他的方法,init(); config();

从写MySecurityConfig时使用的@EnableWebSecurity注解开始看源码:

@EnableWebSecurity`注解导入了三个类,重点关注`WebSecurityConfiguration

我们后面依次分析:

@EnableWebSecurity注解

WebSecurityConfiguration中需要关注两个方法

  1. setFilterChainProxySecurityConfigurer()方法

    创建了WebSecurity建造者对象,用于后面建造FilterChainProxy过滤器

  2. springSecurityFilterChain()方法

    调用WebSecurity.build(),建造出FilterChainProxy过滤器对象