Spring Security多个成功的认证提供商

我希望我的Web应用程序的用户通过LDAP和其他自定义身份validation进行身份validation。 这是一个用Kotlin编写的Spring Boot应用程序。 我已经配置AuthenticationManagerBuilder如下

@Autowired lateinit var authenticationProvider: CustomAuthenticationProvider override fun configure(auth: AuthenticationManagerBuilder) { auth .authenticationProvider(authenticationProvider) auth .ldapAuthentication() .userDnPatterns("uid={0},ou=people") .groupSearchBase("ou=groups") .contextSource() .url("ldap://localhost:8389/dc=example,dc=com") .and() .passwordCompare() .passwordEncoder(PlaintextPasswordEncoder()) .passwordAttribute("userPassword") } 

我想连锁身份validation,以便如果CustomAuthenticationProvider成功身份validation(function身份validation不会抛出)身份validation继续使用LDAP身份validation提供程序。

如果CustomAuthenticationProvider成功进行身份validation,则写入LDAP身份validation(以及任何后续的身份validation提供程序)不会被评估。 只有在CustomAuthenticationProvider引发时才执行LDAP认证。

我已经阅读了许多文章(例如Spring Security中的多个身份validation提供者),详细描述了具有多个身份validation提供程序但具有OR行为而非AND行为的文章。 有什么建议么?

也许我有一些。 但是让我们来分析一下之前的情况。

Spring Security( ProviderManager )中默认的认证管理器实现维护一个认证提供者列表,第一个执行成功认证的代理停止链 – 其余的不被调用。 我相信你不能改变这一点。 当您使用AuthenticationManagerBuilder您将在ProviderManager中添加身份validation提供程序 。

下面的图片显示了一个高层次的概述:

安全架构

在源代码中,这看起来像这样(为简洁起见,跳过细节):

 public Authentication authenticate(Authentication authentication) throws AuthenticationException { Class toTest = authentication.getClass(); ... for (AuthenticationProvider provider : getProviders()) { if (!provider.supports(toTest)) { continue; } try { result = provider.authenticate(authentication); if (result != null) { ... break; } } ... catch (AuthenticationException e) { lastException = e; } } if (result != null) { ... return result; } } 

那么你能做什么…呃。 首先,@dur的问题是有效的:-)其次,显然你不能用标准的认证管理器来做你想做的事情,这对我来说是有意义的。

我认为,如果你仍然想这样做,你可以尝试两件事:

  1. 在您的filter链中提供您自己的validation管理器实施。 这对我来说似乎有些挑战。
  2. 确保您的自定义validation提供程序处理所有必要的validation操作。