首页IT科技spring security authority(在Spring Security中如何获取AuthenticationManager对象?)

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

时间2025-09-18 20:48:17分类IT科技浏览5153
导读:有时需要使用AuthenticationManager(以下简称Manager)对象,可是这个对象不是Bean,没有直接保存在Spring的Bean库中。那么如何获取Spring Security中的这个对象呢?...

有时需要使用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()方法的源码                      。

可以发现在该方法中使用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对象对象做了处理                      ,而方案二并没有做这种处理                      ,推荐使用方案一                      。

声明:本站所有文章,如无特殊说明或标注               ,均为本站原创发布                       。任何个人或组织                      ,在未征得本站同意时        ,禁止复制              、盗用                       、采集        、发布本站内容到任何网站              、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益               ,可联系我们进行处理              。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
nacos有什么用(Nacos 2.2 正式发布,这次更新太炸了!)