我希望我的Web应用程序的用户可以通过LDAP和其他自定义身份验证进行身份验证。它是用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")
}
我想链接身份验证,以便在CustomAuthenticationProvider成功进行身份验证(函数身份验证不抛出)时,使用LDAP身份验证提供程序继续进行身份验证。
如果CustomAuthenticationProvider成功通过身份验证,则不会评估LDAP身份验证(以及任何后续身份验证提供程序)。仅当CustomAuthenticationProvider抛出时才执行LDAP身份验证。
我已阅读了许多文章(例如Multiple Authentication Providers in Spring Security),其中详细介绍了多个身份验证提供程序但具有OR行为而非AND行为。有什么建议吗?
答案 0 :(得分:0)
也许我有一些。但是,让我们分析之前发生的事情。
Spring Security中的默认身份验证管理器实现(ProviderManager)维护一个身份验证提供程序列表,第一个执行成功身份验证的实现程序会停止链 - 其余的不会被调用。我确定你无法改变它。当您使用AuthenticationManagerBuilder
时,可以在ProviderManager。
下图中显示了正在发生的事情的高级概述:
在源代码中,这看起来像这样(为简洁起见,跳过了详细信息):
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
Class<? extends Authentication> 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的问题是有效的:-)第二 - 显然你不能用标准的认证管理器做你想做的事情。这对我来说很有意义。
我认为如果你仍然想要这样做,你可以尝试两件事: