在Spring Security中如何获取AuthenticationManager对象?(spring security auth)

  本篇文章为你整理了在Spring Security中如何获取AuthenticationManager对象?(spring security auth)的详细内容,包含有springsecurity怎么获取用户信息 spring security auth spring security authentication spring security authorization 在Spring Security中如何获取AuthenticationManager对象?,希望能帮助你了解 在Spring Security中如何获取AuthenticationManager对象?。

  有时需要使用AuthenticationManager(以下简称Manager)对象,可是这个对象不是Bean,没有直接保存在Spring的Bean库中。那么如何获取Spring Security中的这个对象呢?

  在Spring Security 5.7.0-M2之前,通常会扩展WebSecurityConfigurerAdapter(以下简称Adapter)类来自定义网络安全配置。Adapter类中有一个方法authenticationManager()可以提供Manager对象。但是从Spring Security 5.7.0-M2开始,Adapter类就被弃用,再用此类中的authenticationManager()方法获取Manager对象就不合适了。

  以下是Adapter#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;

  }

 

  可以发现在该方法中使用Adapter类的私有字段authenticationConfiguration的getAuthenticationManager()方法获取Manager对象。而字段authenticationConfiguration是使用方法setAthenticationConfiguration()自动注入的,所以Spring的Bean库中存在Manager对象。由此可得到如下获取AuthenticationManager对象的方案一。

  方案一:从Spring的Bean库中获取AuthenticationConfiguration(以下简称Configuration)对象,然后使用Configuration对象的getAuthenticationManager()方法获取Manager对象。(关于如何从Spring中获取Bean,本文不作介绍,请读者自行查阅资料了解)

  继续查看Configuration#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;

  }

 

  源码中展示的流程如下。

  ① 如果Configuration对象中已保存有Manager对象,则返回该对象。

  ② 如果Configuration对象中没有Manager对象,则从Spring的Bean库中获取AuthenticationManagerBuilder(以下简称Builder)对象。

  ③ 如果已经用Builder对象构建了Manager对象,则返回一个使用Builder对象初始化的AuthenticationManagerDelegator对象。

  ④ AuthenticationManagerDelegator是Manager的子类。该类代理了另一个Manager对象,被代理的Manager对象是使用Builder对象的getObject()方法获得的。Builder#getObject()的代码表明,在调用该方法前,需要先在Builder对象内构建一个Manager。也就是说可以从Spring的Bean库中获取Builder对象,然后用它的getObject()方法获得Manager对象。

  

@Override

 

  public Authentication authenticate(Authentication authentication) throws AuthenticationException {

   if (this.delegate != null) {

   return this.delegate.authenticate(authentication);

   synchronized (this.delegateMonitor) {

   if (this.delegate == null) {

   this.delegate = this.delegateBuilder.getObject();

   this.delegateBuilder = null;

   return this.delegate.authenticate(authentication);

  }

 

  ⑤ 如果尚未使用Builder对象构建Manager对象,则先把Configuration的私有字段globalAuthConfigurers的数据应用在Builder对象上(私有字段globalAuthConfigurers是通过方法setGlobalAuthConfigurers()自动注入的)。

  ⑥ 然后使用Builder对象的build()方法构建Manager对象。

  ⑦ 在Builder#build()方法中,第一次调用该方法会使用doBuild()方法生成Manager对象(不分析doBuild()方法),并将这个对象缓存下来。以后再调用build()方法将会抛出AlreadyBuiltException异常。也就是说可以从Spring的Bean库中获取Builder对象,然后用它的build()方法获得Manager对象。

  

@Override

 

  public final O build() throws Exception {

   if (this.building.compareAndSet(false, true)) {

   this.object = doBuild();

   return this.object;

   throw new AlreadyBuiltException("This object has already been built");

  }

 

  ⑧ 如果Builder对象未能成功构建Manager对象,则使用Configuration的私有方法lazyBean()方法获取Manager对象(不分析lazyBean()方法)。

  上述流程表明,可以从Spring的Bean库中获取AuthenticationManagerBuilder对象,然后使用该对象的build()方法或getObject()方法获取AuthenticationManager对象。获取AuthenticationManager对象的方案二如下。

  方案二:从Spring的Bean库中获取AuthenticationManagerBuilder对象,首先调用该对象的build()方法获取Manager对象,并对方法调用捕获AlreadyBuiltException异常。若捕获到异常,则在异常处理代码中调用Builder对象的getObject()方法获取Manager对象。

  方案二可能有缺陷。在Configuration#getAuthenticationManager()方法的源码中可以看到步骤⑤对Builder对象对象做了处理,而方案二并没有做这种处理,推荐使用方案一。

  以上就是在Spring Security中如何获取AuthenticationManager对象?(spring security auth)的详细内容,想要了解更多 在Spring Security中如何获取AuthenticationManager对象?的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: