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

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

时间2025-04-30 06:21:17分类IT科技浏览3344
导读:有时需要使用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
startprocessing(shstart.exe – shstart是什么进程 有什么用) 打游戏怎么挣钱最快(如何打游戏赚钱-游戏搬砖打金赚钱避坑指南)