小言_互联网的博客

Spring Security系列-Spring Security生命周期之起源

240人阅读  评论(0)

前言

Springboot项目中,SpringSecurity作为用户认证已经成为标配。在引入SpringSecurity的项目后,我们往往会写一个WebSecurityConfig来配置用户认证规则。接下来,笔者会分三篇文章来介绍,这个认证规则是怎么应用到项目中的。

配置

下面是一个简单的WebSecurity配置,重载了三个config方法。分别配置了登录方式、用户来源和过滤特定url。

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
                .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("admin")
                .password(passwordEncoder.encode("123456"))
                .authorities("admin");
    }

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

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
}

源头

1. SpringBootAutoconfigure

在使用SpringBoot时,我们都可会引用或者间接引用到SpringBootAutoconfigure这个包,而这个包已经包含了一些常用的jar包的默认配置,如大家熟悉的server.port=8080。当然,SpringSecurity的默认配置也会在SpringBootAutoconfigure包内。
SpringBootAutoconfigure包会加载一系列配置类,也包括SpringSecurity的配置类,如下图。

1.1 SecurityAutoConfiguration

其中有一个SecurityAutoConfiguration类,会在项目初始化是被加载。从下面的源代码可以看到SecurityAutoConfiguration类import了WebSecurityEnablerConfiguration类

@Configuration
@ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
@EnableConfigurationProperties(SecurityProperties.class)
@Import({ SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class,
		SecurityDataConfiguration.class })
public class SecurityAutoConfiguration {
	...
}

1.2 WebSecurityEnablerConfiguration

WebSecurityEnablerConfiguration类加上了一个EnableWebSecurity注解

@Configuration
@EnableWebSecurity
public class WebSecurityEnablerConfiguration {

}

1.3 EnableWebSecurity

EnableWebSecurity注解又import了WebSecurityConfiguration类

...
@Import({ WebSecurityConfiguration.class,
		SpringWebMvcImportSelector.class,
		OAuth2ImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
	...
}

1.4 WebSecurityConfiguration

WebSecurityConfiguration类中,有两个比较重要的步骤,如下。

@Configuration
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
	...
	@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
	public Filter springSecurityFilterChain() throws Exception {
		// 这里的webSecurityConfigurers就是我们在程序里的SpringSecurity配置
		boolean hasConfigurers = webSecurityConfigurers != null
				&& !webSecurityConfigurers.isEmpty();
		if (!hasConfigurers) {
			WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
					.postProcess(new WebSecurityConfigurerAdapter() {
					});
			webSecurity.apply(adapter);
		}
		return webSecurity.build();
	}
	...
	@Autowired(required = false)
	public void setFilterChainProxySecurityConfigurer(
			ObjectPostProcessor<Object> objectPostProcessor,
			@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
			throws Exception {
		webSecurity = objectPostProcessor
			.postProcess(new WebSecurity(objectPostProcessor));
		...
		for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
			webSecurity.apply(webSecurityConfigurer);
		}
		this.webSecurityConfigurers = webSecurityConfigurers;
	}
	...
}

一个是setFilterChainProxySecurityConfigurer方法,负责初始化webSecurity和webSecurityConfigurers。webSecurity可以理解为顶层的WebSecurity配置,webSecurityConfigurers是通过beanFactory找到的所有继承WebSecurityConfigurer接口的类,也包括我们自定义的WebSecurity配置。实例化后的顶层webSecurity,再应用其它的webSecurityConfigurers配置。

接下来谈谈另一个重要的方法springSecurityFilterChain的Bean注入。这个springSecurityFilterChain会调用webSecurity的build方法,会根据自定义的WebSecurity配置,来建造相应的规则。

总结

上面介绍了SpringSecurity配置的起源,了解到它是从哪里来的。下一篇会介绍,build方法是怎么建造这些规则的。


转载:https://blog.csdn.net/camel84/article/details/105255344
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场