配置spring security以在使用多个非镜像LDAP服务器的连接异常后继续

时间:2014-07-07 17:00:18

标签: spring spring-security spring-boot spring-security-ldap

我使用带有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:我知道上面有未知的主机异常。我故意为第一台服务器输入一个不正确的主机名,以获得通信类型的异常。当测试期间网络无法临时到达服务器时,会发生同样的事情。

0 个答案:

没有答案