Spring Security 多个成功的身份验证提供程序
Posted
技术标签:
【中文标题】Spring Security 多个成功的身份验证提供程序【英文标题】:Spring Security multiple successful authentication providers 【发布时间】:2018-05-07 18:52:04 【问题描述】:我希望我的 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 行为。有什么建议吗?
【问题讨论】:
这怎么可能?如果您的身份验证提供程序公开身份验证,为什么要 LDAP 进行身份验证,您已经通过身份验证。唯一的方法是,您的身份验证提供程序不会公开身份验证。所以你还没有通过身份验证。 【参考方案1】:也许我有一些。但是让我们分析一下之前的幕后情况。
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 的问题是有效的 :-) 其次 - 很明显,您无法使用对我有意义的标准身份验证管理器来做您想做的事情。
我认为如果你仍然想走那条路,你可以尝试两件事:
-
在您的过滤器链中提供您自己的身份验证管理器实现。这对我来说似乎有点挑战。
确保您的自定义身份验证提供程序处理所有必要的身份验证操作。
【讨论】:
老兄!看java if (result != null) // ... ... break;
你已经猜到了!成功返回null,它会处理下一个!异常会破坏 for 循环。所以,为下一个返回 null,为拒绝而抛出!以上是关于Spring Security 多个成功的身份验证提供程序的主要内容,如果未能解决你的问题,请参考以下文章
特定 url 的多个身份验证提供程序 - Spring Boot Security
Spring Security:针对多个 LDAP 服务器和基于 DAO 的身份验证进行身份验证
Spring security - 身份验证后的 GWT 重定向
防止 Spring Security 通过下一个身份验证提供程序对具有 BadCredentialException 的用户进行身份验证