spring security

Spring Security原理篇(二) 过滤器原理

2018-09-15  本文已影响352人  怪诞140819

上篇文章通过对WebSecurityConfiguration这个配置类的源码阅读,已经了解到,在启动的时候主要创建了两个对象,WebSecurity和名字为springSecurityFilterChainFilter。这篇文章主要是通过源码阅读,查看一下Filter的创建过程,以及后面的工作原理。

1. Filter的创建

1.1再看Filter的创建

/**
     * Creates the Spring Security Filter Chain
     * @return the {@link Filter} that represents the security filter chain
     * @throws Exception
     */
    @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    public Filter springSecurityFilterChain() throws Exception {
        //T1 查看是否有WebSecurityConfigurer的相关配置
        boolean hasConfigurers = webSecurityConfigurers != null
                && !webSecurityConfigurers.isEmpty();
        //T2 如果没有,说明我们没有注入继承WebSecurityConfigurerAdapter 的对象
        if (!hasConfigurers) {
                        
            //T3 创建默认的配置信息WebSecurityConfigurerAdapter ,保证Spring Security的最基础的功能,如果我们要有自定义的相关,一定要重写配置
            WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
                    .postProcess(new WebSecurityConfigurerAdapter() {
                    });
            //T4 默认配置信息载入webSecurity
            webSecurity.apply(adapter);
        }
        // T5这里build一个Filter
        return webSecurity.build();
    }

1.2 WebSecuritybuild()方法

1.2.1 SecurityBuilder接口定义

public interface SecurityBuilder<O> {

    /**
     *
     * Builds the object and returns it or null.
     * @return the Object to be built or null if the implementation allows it.
     * @throws Exception
     *
     */
    O build() throws Exception;
}
public final class WebSecurity extends
        AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements
        SecurityBuilder<Filter>, ApplicationContextAware {
        ...
        ...
}

1.2.2 WebSecuritybuild()过程

@Override
    protected final O doBuild() throws Exception {
        synchronized (configurers) {
            buildState = BuildState.INITIALIZING;
            beforeInit(); //默认什么都没做,WebSecurity也没有重写
            init(); //T1 默认此处调用WebSecurityConfigurerAdapter的init(final WebSecurity web)方法
            buildState = BuildState.CONFIGURING;

            beforeConfigure(); //默认什么都不做,WebSecurity没有重写
            configure();//调用WebSecurityConfigurerAdapter的configure(WebSecurity web),但是什么都没做

            buildState = BuildState.BUILDING;

            O result = performBuild(); //T2这里调用WebSecurity的performBuild()方法

            buildState = BuildState.BUILT;

            return result; //从WebSecurity的实现,这里返回了一个Filter,完成构建过程
        }
    }
    /**
     * @param web
     * @throws Exception
     */
    public void init(final WebSecurity web) throws Exception {
        //构建HttpSecurity对象
        final HttpSecurity http = getHttp();
        web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() {
            public void run() {
                FilterSecurityInterceptor securityInterceptor = http
                        .getSharedObject(FilterSecurityInterceptor.class);
                web.securityInterceptor(securityInterceptor);
            }
        });
    }

这里构建了HttpSecurity对象,以及有一个共享对象FilterSecurityInterceptor ,我们还是要将完整的流程讲完,在下一篇文章对HttpSecurity对象做专门的解读,因为这个HttpSecurity对象扮演者非常重要的角色

@Override
    protected Filter performBuild() throws Exception {
        Assert.state(
                //T1  securityFilterChainBuilders哪里来的?
                !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");
               //T2 ignoredRequests.size()到底是什么?
        int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
                //这个securityFilterChains 的集合里面存放的就是我们所有的过滤器链,根据长度的定义,我们也可以知道分为两种一个是通过ignoredRequests来的过滤器链,一个是通过securityFilterChainBuilders这个过滤器链构建链来的。
        List<SecurityFilterChain> securityFilterChains = new ArrayList<>(
                chainSize);

                //如果是ignoredRequest类型的,那么久添加默认过滤器链(DefaultSecurityFilterChain)
        for (RequestMatcher ignoredRequest : ignoredRequests) {
            securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
        }
               
                //如果是securityFilterChainBuilder类型的,那么通过securityFilterChainBuilder的build()方法来构建过滤器链
        for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
            securityFilterChains.add(securityFilterChainBuilder.build());
        }
               
            //将过滤器链交给一个过滤器链代理对象,而这个代理对象就是返回回去的过滤器,后面的代码先不做交代。到这里为止,过滤器的过程已经结束
             //T3 什么是FilterChainProxy? 
        FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
        if (httpFirewall != null) {
            filterChainProxy.setFirewall(httpFirewall);
        }
        filterChainProxy.afterPropertiesSet();

        Filter result = filterChainProxy;
        if (debugEnabled) {
            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");
            result = new DebugFilter(filterChainProxy);
        }
        postBuildAction.run();
        return result;
    }

从上面源码和标注的注释(也许理解不透彻)来看,其实我们只要回答清楚上面的T1,T2,T3这三个问题,就基本弄清楚了。

1.2.3 WebSecuritysecurityFilterChainBuilders属性哪里来的

       /**
     * @param web
     * @throws Exception
     */
    public void init(final WebSecurity web) throws Exception {
        final HttpSecurity http = getHttp();
               
                //T1
        web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() {
            public void run() {
                FilterSecurityInterceptor securityInterceptor = http
                        .getSharedObject(FilterSecurityInterceptor.class);
                web.securityInterceptor(securityInterceptor);
            }
        });
    }
public WebSecurity addSecurityFilterChainBuilder(
            SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder) {
                 //这个就是securityFilterChainBuilders变量
        this.securityFilterChainBuilders.add(securityFilterChainBuilder);
        return this;
    }

1.2.4 ignoredRequests到底是什么

public void configure(WebSecurity web) throws Exception {
}
@Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
        web.ignoring()
           .mvcMatchers("/favicon.ico", "/webjars/**", "/css/**");
    }

1.2.5 FilterChainProxy到底是什么

 FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);

1.3 过滤器实现的流程

Filter创建过程.png

我们暂时的放过一下FilterChainProxy,下一篇我们继续HttpSecurity

上一篇 下一篇

猜你喜欢

热点阅读