spring security经常在项目中用到,但是平常只是简单的使用肯定是不够的,我们需要了解深层次的东西,才能在使用的过程中不畏惧,本次打算从demo入手,跟踪源码,剖析security内在
环境
springboot: 2.3.4.RELEASE spring security :spring-boot-starter-security版本跟随springboot
一、springboot默认自动配置了security,我们看下security相关类都是在什么情况下加载的
如上图,securityAutoConfiguration是spirngboot自动配置文件中的类
二、security各相关类的继承关系
三、服务启动创建相关对象
1、首先创建的是WebSecurityConfigurerAdapter对象 2、创建AuthenticationConfiguration对象,并根据@Bean注解分别创建了GlobalAuthenticationConfigurerAdapter 、InitializeUserDetailsBeanManagerConfigurer(继承GlobalAuthenticationConfigurerAdapter) 、InitializeAuthenticationProviderBeanManagerConfigurer(继承GlobalAuthenticationConfigurerAdapter)
@Configuration(proxyBeanMethods = false)
@Import(ObjectPostProcessorConfiguration.class)
public class AuthenticationConfiguration {
private AtomicBoolean buildingAuthenticationManager = new AtomicBoolean();
private ApplicationContext applicationContext;
private AuthenticationManager authenticationManager;
private boolean authenticationManagerInitialized;
private List<GlobalAuthenticationConfigurerAdapter> globalAuthConfigurers = Collections
.emptyList();
private ObjectPostProcessor<Object> objectPostProcessor;
@Bean
public AuthenticationManagerBuilder authenticationManagerBuilder(
ObjectPostProcessor<Object> objectPostProcessor, ApplicationContext context) {
LazyPasswordEncoder defaultPasswordEncoder = new LazyPasswordEncoder(context);
AuthenticationEventPublisher authenticationEventPublisher = getBeanOrNull(context, AuthenticationEventPublisher.class);
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor, defaultPasswordEncoder);
if (authenticationEventPublisher != null) {
result.authenticationEventPublisher(authenticationEventPublisher);
}
return result;
}
@Bean
public static GlobalAuthenticationConfigurerAdapter enableGlobalAuthenticationAutowiredConfigurer(
ApplicationContext context) {
return new EnableGlobalAuthenticationAutowiredConfigurer(context);
}
@Bean
public static InitializeUserDetailsBeanManagerConfigurer initializeUserDetailsBeanManagerConfigurer(ApplicationContext context) {
return new InitializeUserDetailsBeanManagerConfigurer(context);
}
@Bean
public static InitializeAuthenticationProviderBeanManagerConfigurer initializeAuthenticationProviderBeanManagerConfigurer(ApplicationContext context) {
return new InitializeAuthenticationProviderBeanManagerConfigurer(context);
}
3、创建AuthenticationManagerBuilder ,如下图,创建DefaultPasswordEncoderAuthenticationManagerBuilder(内部类,继承AuthenticationManagerBuilder) 4、创建WebSecurityConfiguration 5、创建webSecurity 6、创建Filter(调用webSecutity的build方法) build方法会进入父类的doBuild 次时SecurityConfigurer类型的configurers只有webSecurityConfigurerAdapter 进入webSecurityConfigurerAdapter的init方法 进入getHttp方法
protected final HttpSecurity getHttp() throws Exception {
if (http != null) {
return http;
}
AuthenticationManager authenticationManager = authenticationManager();
authenticationBuilder.parentAuthenticationManager(authenticationManager);
Map<Class<?>, Object> sharedObjects = createSharedObjects();
http = new HttpSecurity(objectPostProcessor, authenticationBuilder,
sharedObjects);
if (!disableDefaults) {
http
.csrf().and()
.addFilter(new WebAsyncManagerIntegrationFilter())
.exceptionHandling().and()
.headers().and()
.sessionManagement().and()
.securityContext().and()
.requestCache().and()
.anonymous().and()
.servletApi().and()
.apply(new DefaultLoginPageConfigurer<>()).and()
.logout();
ClassLoader classLoader = this.context.getClassLoader();
List<AbstractHttpConfigurer> defaultHttpConfigurers =
SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);
for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
http.apply(configurer);
}
}
configure(http);
return http;
}
========================================================================================= 进入代码片段001 进入build方法类似之前进入的build,三个配置分别调用init方法 重点关注InitializeUserDetailsBeanManagerConfigurer的init方法,主要加载了UserDetailService接口实现类,以及PasswordEncoder接口实现类 至此,代码片段一基本结束
|