文章概述
本文主要解决几个问题:
- security配置生效的入口是哪里
- 我们平时写的security配置是如何被调用的
- 为什么我们写的配置需要继承WebSecurityConfigurerAdapter
- HttpSecurity和WebSecurity是干嘛用的
配置核心类
- 启动Security,需要在启动类上添加
@EnableSecurity
注解
@SpringBootApplication
@EnableWebSecurity
public class ThingsboardApp {
...
}
@EnableSecurity
解析
@Import({
WebSecurityConfiguration.class,
SpringWebMvcImportSelector.class,
OAuth2ImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
/**
* Controls debugging support for Spring Security. Default is false.
* @return if true, enables debug support with Spring Security
*/
boolean debug() default false;
}
@EnableSecurity
注解通过@Import
引入了WebSecurityConfiguration作为bean。
- WebSecurityConfiguration类,是一个bean,spring启动后,关于security的配置生效从这里开始。
@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
...
}
实现了ImportAware接口,ImportAware接口作用是将引入了@Import
注解的类的AnnotationMetadata信息通过setImportMetadata
方法传入ImportAware的实现类中。借鉴点:@Import
是叠加在@EnableSecurity
注解上的,而@EnableSecurity又是注解在启动类上的,于是在WebSecurityConfiguration类就能拿到启动类上的注解信息,通常关心的是@EnableXXXX
注解的信息,因为这里可能包含一些开启的配置信息。
实现了BeanClassLoaderAware接口,将Spring容器的BeanClassLoader设置到属性中,目前没看到有用到这个属性。
配置注入
WebSecurityConfiguration类
@Autowired(required = false)
public void setFilterChainProxySecurityConfigurer(
ObjectPostProcessor<Object> objectPostProcessor,
@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
throws Exception {
...
}
方法参数利用SPEL将注入类型为WebSecurityConfigurer.class的bean,WebSecurityConfigurer的重要实现类WebSecurityConfigurerAdapter,是我们配置security通常需要继承的基类。于是这里拿到了我们的配置bean,将它们设置到webSecurityConfigurers属性中。
配置生效入口
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
..