简介
在构建WenSecurity执行生命周期AbstractConfiguredSecurityBuilder#doBuild()方法中的init(),会执行到WebSecurityConfigurerAdapter#init(WebSecurity web) 方法,会去创建HttpSecurity。在创建HttpSecurity时调用authenticationManager()构建ProviderManager。
WebSecurityConfigurerAdapter#authenticationManager()
protected AuthenticationManager authenticationManager() throws Exception {
if (!this.authenticationManagerInitialized) {
configure(this.localConfigureAuthenticationBldr);
if (this.disableLocalConfigureAuthenticationBldr) {
this.authenticationManager = this.authenticationConfiguration.getAuthenticationManager();
}
else {
this.authenticationManager = this.localConfigureAuthenticationBldr.build();
}
this.authenticationManagerInitialized = true;
}
return this.authenticationManager;
}
默认调用authenticationConfiguration.getAuthenticationManager()构建AuthenticationManager,即ProviderManager。authenticationConfiguration是通过@Autowired自动注入的。
AuthenticationConfiguration来源
@EnableWebSecurity注解导入了@EnableGlobalAuthentication,看看@EnableGlobalAuthentication定义:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(AuthenticationConfiguration.class)
@Configuration
public @interface EnableGlobalAuthentication {
}
@EnableGlobalAuthentication导入了配置类AuthenticationConfiguration。这个AuthenticationConfiguration就是WebSecurityConfigurerAdapter中的AuthenticationConfiguration字段要注入的配置类。
看看AuthenticationConfiguration类中重要的方法:
@Bean
public AuthenticationManagerBuilder authenticationManagerBuilder(ObjectPostProcessor<Object> objectPostProcessor,
ApplicationContext context) {
LazyPasswordEncoder defaultPasswordEncoder = new LazyPasswordEncoder(context);
AuthenticationEventPublisher authenticationEventPublisher = getAuthenticationEventPublisher(context);
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);
}
创建了一个DefaultPasswordEncoderAuthenticationManagerBuilder bean和三个类型GlobalAuthenticationConfigurerAdapter的bean。
现在看看authenticationConfiguration.getAuthenticationManager():
public AuthenticationManager getAuthenticationManager() throws Exception {
if (this.authenticationManagerInitialized) {
return this.authenticationManager;
}
AuthenticationManagerBuilder authBuilder = this.applicationContext.getBean(AuthenticationManagerBuilder.class);
if (this.buildingAuthenticationManager.getAndSet(true)) {
return new AuthenticationManagerDelegator(authBuilder);
}
for (GlobalAuthenticationConfigurerAdapter config : this.globalAuthConfigurers) {
authBuilder.apply(config);
}
this.authenticationManager = authBuilder.build();
if (this.authenticationManager == null) {
this.authenticationManager = getAuthenticationManagerBean();
}
this.authenticationManagerInitialized = true;
return this.authenticationManager;
}
authBuilder就是上面的DefaultPasswordEncoderAuthenticationManagerBuilder。globalAuthConfigurers集合就是上面的EnableGlobalAuthenticationAutowiredConfigurer,InitializeUserDetailsBeanManagerConfigurer,InitializeAuthenticationProviderBeanManagerConfigurer。调用authBuilder.apply方法将EnableGlobalAuthenticationAutowiredConfigurer,InitializeUserDetailsBeanManagerConfigurer,InitializeAuthenticationProviderBeanManagerConfigurer加入到DefaultPasswordEncoderAuthenticationManagerBuilder的configurers属性中。
调用authBuilder.build()创建AuthenticationManager。
DefaultPasswordEncoderAuthenticationManagerBuilder类继承结构如下:
DefaultPasswordEncoderAuthenticationManagerBuilder继承了AbstractConfiguredSecurityBuilder。DefaultPasswordEncoderAuthenticationManagerBuilder#build()会调用到AbstractConfiguredSecurityBuilder#doBuild()执行生命周期构建。重点看init(),configure(),performBuild()。init()方法会调用configurers集合的中每个元素的init()方法。DefaultPasswordEncoderAuthenticationManagerBuilder中的configurers集合有EnableGlobalAuthenticationAutowiredConfigurer,InitializeUserDetailsBeanManagerConfigurer,InitializeAuthenticationProviderBeanManagerConfigurer。
DefaultPasswordEncoderAuthenticationManagerBuilder执行configurer类的init方法
EnableGlobalAuthenticationAutowiredConfigurer#init(AuthenticationManagerBuilder auth)
@Override
public void init(AuthenticationManagerBuilder auth) {
Map<String, Object> beansWithAnnotation = this.context
.getBeansWithAnnotation(EnableGlobalAuthentication.class);
if (logger.isTraceEnabled()) {
logger.trace(LogMessage.format("Eagerly initializing %s", beansWithAnnotation));
}
}
打印了日志。
先分别执行EnableGlobalAuthenticationAutowiredConfigurer,InitializeUserDetailsBeanManagerConfigurer,InitializeAuthenticationProviderBeanManagerConfigurer的init方法。
InitializeAuthenticationProviderBeanManagerConfigurer#init(AuthenticationManagerBuilder auth)
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.apply(new InitializeAuthenticationProviderManagerConfigurer());
}
将InitializeAuthenticationProviderManagerConfigurer配置加入到DefaultPasswordEncoderAuthenticationManagerBuilder中的configurersAddedInInitializing属性和configurers属性。
InitializeUserDetailsBeanManagerConfigurer#init(AuthenticationManagerBuilder auth)
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.apply(new InitializeUserDetailsManagerConfigurer());
}
将InitializeUserDetailsManagerConfigurer配置加入到DefaultPasswordEncoderAuthenticationManagerBuilder中的configurersAddedInInitializing属性和configurers属性。
执行完后DefaultPasswordEncoderAuthenticationManagerBuilder中的configurers集合有五个元素。执行完EnableGlobalAuthenticationAutowiredConfigurer,InitializeUserDetailsBeanManagerConfigurer,InitializeAuthenticationProviderBeanManagerConfigurer的init方法后又执行InitializeAuthenticationProviderManagerConfigurer,InitializeUserDetailsManagerConfigurer的init方法,这两个类的init方法是空方法,就不谈了。
DefaultPasswordEncoderAuthenticationManagerBuilder执行configurer类的configure方法
现在分别执行上面五个configurer的configure方法。三个类EnableGlobalAuthenticationAutowiredConfigurer,InitializeUserDetailsBeanManagerConfigurer,InitializeAuthenticationProviderBeanManagerConfigurer的configure是空方法就不谈了。
InitializeAuthenticationProviderManagerConfigurer#configure(AuthenticationManagerBuilder auth)
@Override
public void configure(AuthenticationManagerBuilder auth) {
if (auth.isConfigured()) {
return;
}
AuthenticationProvider authenticationProvider = getBeanOrNull(AuthenticationProvider.class);
if (authenticationProvider == null) {
return;
}
auth.authenticationProvider(authenticationProvider);
}
默认AuthenticationProvider是null。
InitializeUserDetailsManagerConfigurer#configure(AuthenticationManagerBuilder auth)
public void configure(AuthenticationManagerBuilder auth) throws Exception {
if (auth.isConfigured()) {
return;
}
UserDetailsService userDetailsService = getBeanOrNull(UserDetailsService.class);
if (userDetailsService == null) {
return;
}
PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);
UserDetailsPasswordService passwordManager = getBeanOrNull(UserDetailsPasswordService.class);
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
if (passwordEncoder != null) {
provider.setPasswordEncoder(passwordEncoder);
}
if (passwordManager != null) {
provider.setUserDetailsPasswordService(passwordManager);
}
provider.afterPropertiesSet();
auth.authenticationProvider(provider);
}
创建了DaoAuthenticationProvider并添加到DefaultPasswordEncoderAuthenticationManagerBuilder的authenticationProviders字段中。
DefaultPasswordEncoderAuthenticationManagerBuilder执行performBuild方法
AuthenticationManagerBuilder#performBuild()
protected ProviderManager performBuild() throws Exception {
if (!isConfigured()) {
this.logger.debug("No authenticationProviders and no parentAuthenticationManager defined. Returning null.");
return null;
}
ProviderManager providerManager = new ProviderManager(this.authenticationProviders,
this.parentAuthenticationManager);
if (this.eraseCredentials != null) {
providerManager.setEraseCredentialsAfterAuthentication(this.eraseCredentials);
}
if (this.eventPublisher != null) {
providerManager.setAuthenticationEventPublisher(this.eventPublisher);
}
providerManager = postProcess(providerManager);
return providerManager;
}
将authenticationProviders集合添加到ProviderManager中。authenticationProviders默认是DaoAuthenticationProvider。调用postProcess让ProviderManager执行Spring的Bean创建流程。
标签:AuthenticationManagerBuilder,ProviderManager,return,auth,SpringSecurity,init,源码, From: https://www.cnblogs.com/shigongp/p/17304115.html