我使用带有Spring Boot的Spring Security进行了成功配置,该配置将检查四个不同的LDAP提供程序以获取传递给它的用户凭据。如果用户不在第一个服务器中,则检查第二个服务器,依此类推。如果所有提供商都可用,这将完美地运行。但是,如果其中一个提供程序已关闭,则身份验证链将停止,并且spring将返回未授权的异常。
身份验证适用于基于REST的服务,因此使用故障处理程序重定向到不同的URL似乎不会对此有所帮助。
我知道上下文源中的urls属性,但是我可以确定它仅用于故障转移到与主LDAP服务器具有相同配置的镜像LDAP服务器。在此配置中情况并非如此,每个LDAP服务器都有自己独立且不同的配置。
我检查了多个StackOverflow问题以及Spring文档和归档论坛。我看到的所有问题和配置要么是镜像故障转移配置,要么与我的配置基本相同。
我通过Groovy类配置的当前配置和AuthenticationManager设置如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
http.httpBasic().realmName("Service Authorization")
}
@Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
authManagerBuilder.ldapAuthentication()
.userSearchFilter("${ldapExtConfig.userSearchFilter}")
.contextSource().url("${ldapExtConfig.url}/${ldapExtConfig.baseDn}")
.managerDn("${ldapExtConfig.managerDn}")
.managerPassword("${ldapExtConfig.managerPassword}")
authManagerBuilder.ldapAuthentication()
.userSearchFilter("${ldapAmerConfig.userSearchFilter}")
.contextSource().url("${ldapAmerConfig.url}/${ldapAmerConfig.baseDn}")
.managerDn("${ldapAmerConfig.managerDn}")
.managerPassword("${ldapAmerConfig.managerPassword}")
authManagerBuilder.ldapAuthentication()
.userSearchFilter("${ldapEmeaConfig.userSearchFilter}")
.contextSource().url("${ldapEmeaConfig.url}/${ldapEmeaConfig.baseDn}")
.managerDn("${ldapEmeaConfig.managerDn}")
.managerPassword("${ldapEmeaConfig.managerPassword}")
authManagerBuilder.ldapAuthentication()
.userSearchFilter("${ldapApacConfig.userSearchFilter}")
.contextSource().url("${ldapApacConfig.url}/${ldapApacConfig.baseDn}")
.managerDn("${ldapApacConfig.managerDn}")
.managerPassword("${ldapApacConfig.managerPassword}")
}
我可以将其拆分为多个war / jar文件,因为Spring Boot是轻量级的,但该解决方案被服务器管理器拒绝。我是否必须考虑实现自定义身份验证提供程序并尝试包装尝试序列?
有没有办法让Spring Security继续尝试后续的AuthenticationProviders,如果第一个无法连接?我认为这应该是可能的,否则能够指定多种类型的提供者的效用有限。谢谢!
更新:我已经做了一些工作来在本地复制它,我无法让它按照我认为的那样工作。即使将Spring Security日志记录设置为DEBUG,我也无法获取日志消息。我能够在JSON响应中获得一些额外的信息,这些信息正在传递给我。主机名在下面的消息中被故意更改。
{
"error": "Unauthorized",
"message": "ldapserver:636; nested exception is javax.naming.CommunicationException: ldapserver:636 [Root exception is java.net.UnknownHostException: ldapserver]",
"status": 401,
"timestamp": 1404924353023
}
所以似乎正在发生的事情是Spring Security LDAP提供程序正在包装通信异常,而不是记录它,并自动将其转换为Unauthorized异常。这不是我预期的行为,特别是因为我在配置中指定了多个提供程序。
更新2:我知道上面有未知的主机异常。我故意为第一台服务器输入一个不正确的主机名,以获得通信类型的异常。当测试期间网络无法临时到达服务器时,会发生同样的事情。