我使用带有 Spring Boot 的 Spring Security 进行了成功的配置,它将检查四个不同的 LDAP 提供程序以获取传递给它的用户凭据。如果用户不在第一台服务器中,则检查第二台服务器,依此类推。如果所有提供程序都可用,这将非常有效。但是,如果其中一个提供程序关闭,则身份验证链停止并且 spring 返回一个未经授权的异常。
身份验证适用于基于 REST 的服务,因此使用故障处理程序重定向到不同的 URL 似乎对这种情况没有帮助。
我知道上下文源上的 urls 属性,但据我所知,它仅用于故障转移到与主 LDAP 服务器具有相同配置的镜像 LDAP 服务器。在此配置中并非如此,每个 LDAP 服务器都有自己独立且不同的配置。
我检查了多个 StackOverflow 问题以及 Spring 文档和存档论坛。我看到的所有问题和配置要么是针对镜像故障转移配置,要么与我的配置基本相同。
我当前的配置和 AuthenticationManager 设置是通过 Groovy 类配置的,如下所示:
@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 提供程序正在包装通信异常,而不是记录它,并自动将其转换为未经授权的异常。这不是我预期的行为,特别是因为我在配置中指定了多个提供程序。
更新 2:我知道上面说的是未知主机异常。我故意为第一台服务器输入了不正确的主机名,以获得通信类型的异常。当网络在测试期间暂时无法访问服务器时,也会发生相同类型的事情。