springboot springsecurity

用户可以创建一个WebSecurityConfigurerAdapter的子类,然后在configure方法中配置认证授权条件,这些条件会转化为一个个的SecurityConfigurer的子类,他们会被放到一个名为configurers的hashmap里,在AbstractConfiguredSecurityBuilder的configure方法中会获取configurers中的所有SecurityConfigurer,然后依次调用他们的configure方法。这些configure方法主要还是注册filter到filterchain。


我们从@EnableWebSecurity注解说起

@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = { java.lang.annotation.ElementType.TYPE })
@Documented
@Import({ WebSecurityConfiguration.class,
        SpringWebMvcImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity

这里有个很重要的类WebSecurityConfiguration他里面有个方法:

@Autowired(required = false)
    public void setFilterChainProxySecurityConfigurer(
            ObjectPostProcessor<Object> objectPostProcessor,
            @Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
            throws Exception {


这个方法会把spring上下文中的实现了SecurityConfigurer的所有的bean都放到一个webSecurity对象的configurers中,其实一般我们做自定义配置时是要实现一个WebSecurityConfigurerAdapter的子类,WebSecurityConfigurerAdapter实现了SecurityConfigurer接口,所以我们定义的类会被放到webSecurity对象的configurers中,后面分析会用到。

再来看WebSecurityConfiguration的另一个方法

@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    public Filter springSecurityFilterChain() throws Exception

这里AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME=“springSecurityFilterChain”

也即是这里通过springSecurityFilterChain方法向spring上下文添加了一个名为springSecurityFilterChain的bean,后面分析会用到

接着看springSecurityFilterChain这个方法他调用了webSecurity.build()->doBuild()->init()

@SuppressWarnings("unchecked")
    private void init() throws Exception {
        Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

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

可以看到getConfigurers会获取到我们之前提到的configurers,然后这里就是一次调用configurer的init()方法,注意这里的(B) this是webSecurity对象,后续还会出现httpSecurity对象,所以比较混乱,一般我们实现WebSecurityConfigurerAdapter的子类不会覆盖init方法,所以这里就用的WebSecurityConfigurerAdapter的init方法。

public void init(final WebSecurity web) throws Exception {
        final HttpSecurity http = getHttp();
        web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() {
            public void run() {
                FilterSecurityInterceptor securityInterceptor = http
                        .getSharedObject(FilterSecurityInterceptor.class);
                web.securityInterceptor(securityInterceptor);
            }
        });
    }



猜你喜欢

转载自blog.51cto.com/2839840/2345352