0


AuthenticationManager

文章目录

1.了解

1.1ProviderManager

ProviderManager管理了一个AuthenticationProvider列表,每个AuthenticationProvider都是一个认证器

ProviderManager 相当于代理了多个 AuthenticationProvider,他们的关系如下图:
在这里插入图片描述

1.2AuthenticationProvider

publicinterfaceAuthenticationProvider{Authenticationauthenticate(Authentication var1)throwsAuthenticationException;booleansupports(Class<?> var1);}

AuthenticationProvider

  • authenticate方法来验证,就是验证用户身份在这里插入图片描述
  • supports用来判断当前AuthenicationProvider是否对应支持Authentication

1.3Parent

  • 一个ProviderManager管理多个AuthenticationPorvider
  • 每一个ProviderManager可以配置一个parent
  • 如果当前的 ProviderManager 中认证失败了,还可以去它的 parent 中继续执行认证(一般还是ProviderManager)

在这里插入图片描述

AuthenticationManager 的初始化会分为两块,

一个全局的 AuthenticationManager,也就是 parent,另一个则是局部的 AuthenticationManager。

先给大家一个结论,一个系统中,我们可以配置多个 HttpSecurity(参见Spring Security 竟然可以同时存在多个过滤器链?),而每一个 HttpSecurity 都有一个对应的 AuthenticationManager 实例(局部 AuthenticationManager),这些局部的 AuthenticationManager 实例都有一个共同的 parent,那就是全局的 AuthenticationManager。

2.源码分析

在这里插入图片描述

AuthenticationManagerBuilder 源码比较长,我们来看几个关键的方法

publicclassAuthenticationManagerBuilderextendsAbstractConfiguredSecurityBuilder<AuthenticationManager,AuthenticationManagerBuilder>implementsProviderManagerBuilder<AuthenticationManagerBuilder>{publicAuthenticationManagerBuilder(ObjectPostProcessor<Object> objectPostProcessor){super(objectPostProcessor,true);}publicAuthenticationManagerBuilderparentAuthenticationManager(AuthenticationManager authenticationManager){if(authenticationManager instanceofProviderManager){eraseCredentials(((ProviderManager) authenticationManager).isEraseCredentialsAfterAuthentication());}this.parentAuthenticationManager = authenticationManager;returnthis;}publicInMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>inMemoryAuthentication()throwsException{returnapply(newInMemoryUserDetailsManagerConfigurer<>());}publicJdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder>jdbcAuthentication()throwsException{returnapply(newJdbcUserDetailsManagerConfigurer<>());}public<TextendsUserDetailsService>DaoAuthenticationConfigurer<AuthenticationManagerBuilder,T>userDetailsService(T userDetailsService)throwsException{this.defaultUserDetailsService = userDetailsService;returnapply(newDaoAuthenticationConfigurer<>(
    userDetailsService));}@OverrideprotectedProviderManagerperformBuild()throwsException{if(!isConfigured()){
   logger.debug("No authenticationProviders and no parentAuthenticationManager defined. Returning null.");returnnull;}ProviderManager providerManager =newProviderManager(authenticationProviders,
    parentAuthenticationManager);if(eraseCredentials !=null){
   providerManager.setEraseCredentialsAfterAuthentication(eraseCredentials);}if(eventPublisher !=null){
   providerManager.setAuthenticationEventPublisher(eventPublisher);}
  providerManager =postProcess(providerManager);return providerManager;}}

步骤分析:

1.首先,我们调用parentAuthenticationManager 给AuthenticationManager 设置parent
2.inMemoryAuthentication、jdbcAuthentication 以及 userDetailsService 几个方法是配置数据源
3.performBuild方法,根据AuthenticationManagerBuilder构建AuthenticationManager  
 构建ProviderManager,一方面传入authenticationProviders(就是ProviderManager 管理的所有AuthenticationProvider),另一方面传入ProviderManager 的 parent(其实也是一个 ProviderManager)

2.1初始化

AuthenticationConfiguration ,这个类可以当做

@Configuration(proxyBeanMethods =false)@Import(ObjectPostProcessorConfiguration.class)publicclassAuthenticationConfiguration{@BeanpublicAuthenticationManagerBuilderauthenticationManagerBuilder(ObjectPostProcessor<Object> objectPostProcessor,ApplicationContext context){LazyPasswordEncoder defaultPasswordEncoder =newLazyPasswordEncoder(context);AuthenticationEventPublisher authenticationEventPublisher =getBeanOrNull(context,AuthenticationEventPublisher.class);DefaultPasswordEncoderAuthenticationManagerBuilder result =newDefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor, defaultPasswordEncoder);if(authenticationEventPublisher !=null){
   result.authenticationEventPublisher(authenticationEventPublisher);}return result;}@BeanpublicstaticGlobalAuthenticationConfigurerAdapterenableGlobalAuthenticationAutowiredConfigurer(ApplicationContext context){returnnewEnableGlobalAuthenticationAutowiredConfigurer(context);}@BeanpublicstaticInitializeUserDetailsBeanManagerConfigurerinitializeUserDetailsBeanManagerConfigurer(ApplicationContext context){returnnewInitializeUserDetailsBeanManagerConfigurer(context);}@BeanpublicstaticInitializeAuthenticationProviderBeanManagerConfigurerinitializeAuthenticationProviderBeanManagerConfigurer(ApplicationContext context){returnnewInitializeAuthenticationProviderBeanManagerConfigurer(context);}publicAuthenticationManagergetAuthenticationManager()throwsException{if(this.authenticationManagerInitialized){returnthis.authenticationManager;}AuthenticationManagerBuilder authBuilder =this.applicationContext.getBean(AuthenticationManagerBuilder.class);if(this.buildingAuthenticationManager.getAndSet(true)){returnnewAuthenticationManagerDelegator(authBuilder);}for(GlobalAuthenticationConfigurerAdapter config : globalAuthConfigurers){
   authBuilder.apply(config);}

  authenticationManager = authBuilder.build();if(authenticationManager ==null){
   authenticationManager =getAuthenticationManagerBean();}this.authenticationManagerInitialized =true;return authenticationManager;}@AutowiredpublicvoidsetApplicationContext(ApplicationContext applicationContext){this.applicationContext = applicationContext;}@AutowiredpublicvoidsetObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor){this.objectPostProcessor = objectPostProcessor;}privatestaticclassEnableGlobalAuthenticationAutowiredConfigurerextendsGlobalAuthenticationConfigurerAdapter{privatefinalApplicationContext context;privatestaticfinalLog logger =LogFactory.getLog(EnableGlobalAuthenticationAutowiredConfigurer.class);EnableGlobalAuthenticationAutowiredConfigurer(ApplicationContext context){this.context = context;}@Overridepublicvoidinit(AuthenticationManagerBuilder auth){Map<String,Object> beansWithAnnotation = context
     .getBeansWithAnnotation(EnableGlobalAuthentication.class);if(logger.isDebugEnabled()){
    logger.debug("Eagerly initializing "+ beansWithAnnotation);}}}}

一言以蔽之,AuthenticationConfiguration 中的配置有没有用上,全看开发者有没有重写

configure(AuthenticationManagerBuilder auth)

方法,重写了,就用 localConfigureAuthenticationBldr 来构建 parent 级别的 AuthenticationManager,没重写,就用 AuthenticationConfiguration 中的方法来构建。

标签: 安全

本文转载自: https://blog.csdn.net/weixin_45802793/article/details/121891982
版权归原作者 南一道街丶 所有, 如有侵权,请联系我们删除。

“AuthenticationManager”的评论:

还没有评论