You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成Spring Security通过AD域认证时域名连接失败

Active Directory认证使用域名时连接拒绝的问题排查与解决

问题重现

你在使用Spring Security的ActiveDirectoryLdapAuthenticationProvider实现AD用户认证时,自定义了CustomLdapAuthenticationProvider类,核心代码如下:

@Override 
public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
    ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider = new ActiveDirectoryLdapAuthenticationProvider("companyDomain", "ldap://companyDomain:389", "rootDN"); 
    activeDirectoryLdapAuthenticationProvider.setConvertSubErrorCodesToExceptions(true); 
    activeDirectoryLdapAuthenticationProvider.setUseAuthenticationRequestCredentials(true); 
    activeDirectoryLdapAuthenticationProvider.setSearchFilter("(userPrincipalName={0})"); 
    activeDirectoryLdapAuthenticationProvider.setUserDetailsContextMapper(customUserDetailsContextMapper); 
    authentication = activeDirectoryLdapAuthenticationProvider.authenticate(authentication); 
    return authentication; 
} 

当LDAP URL使用IP地址(ldap://x.x.x.x:389)时认证成功,但切换为域名(ldap://companyDomain:389)时抛出连接拒绝异常,关键错误栈如下:

2018-05-16 22:57:23.711 ERROR 11552 --- [nio-8080-exec-9] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/api] threw exception 
org.springframework.ldap.CommunicationException: companyDomain:389; nested exception is javax.naming.CommunicationException: companyDomain:389 [Root exception is java.net.ConnectException: Connection refused: connect] 
at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:108) ~[spring-ldap-core-2.3.2.RELEASE.jar:2.3.2.RELEASE]
...

原因分析

这种"IP能通、域名不通"的问题,通常和域名解析、ActiveDirectoryLdapAuthenticationProvider的内部逻辑或网络策略有关,具体拆解:

  • DNS解析失败:应用服务器无法将companyDomain解析到正确的AD服务器IP,导致连接请求发往错误地址被拒绝。
  • AD自动发现机制问题:ActiveDirectoryLdapAuthenticationProvider的第一个参数是AD域名,当你传入域名形式的URL时,它可能会尝试通过DNS SRV记录自动查找AD服务器,如果SRV记录配置缺失或错误,就会连接失败。
  • 网络/防火墙限制:域名解析后的AD服务器IP,其389端口可能被应用服务器的防火墙或网络策略拦截,而你测试的IP恰好是另一个允许访问的节点。
  • 重复初始化Provider:你在每次authenticate调用时都新建ActiveDirectoryLdapAuthenticationProvider实例,可能导致DNS缓存或连接池的问题,影响域名解析的稳定性。

解决方案

针对上述原因,逐一给出解决步骤:

1. 验证DNS解析正确性

  • 在应用服务器上执行ping companyDomain,确认返回的IP是你已知可用的AD服务器IP。如果解析错误,可临时在服务器的hosts文件中添加companyDomain与对应IP的映射(Linux路径/etc/hosts,Windows路径C:\Windows\System32\drivers\etc\hosts),测试是否能正常认证。
  • 执行nslookup -type=SRV _ldap._tcp.companyDomain,检查是否存在LDAP服务的SRV记录。如果没有,联系AD管理员配置正确的SRV记录,这是AD自动发现的关键。

2. 优化Provider配置与使用方式

  • 避免重复初始化Provider:不要在authenticate方法内每次都新建ActiveDirectoryLdapAuthenticationProvider,改为Spring Bean注入的方式,这样能复用连接池和解析缓存,更符合Spring最佳实践:
// 配置AD Provider为Bean
@Bean
public ActiveDirectoryLdapAuthenticationProvider adAuthenticationProvider() {
    ActiveDirectoryLdapAuthenticationProvider provider = 
        new ActiveDirectoryLdapAuthenticationProvider("companyDomain", "ldap://companyDomain:389", "rootDN");
    provider.setConvertSubErrorCodesToExceptions(true);
    provider.setUseAuthenticationRequestCredentials(true);
    provider.setSearchFilter("(userPrincipalName={0})");
    provider.setUserDetailsContextMapper(customUserDetailsContextMapper);
    return provider;
}

// 在自定义Provider中注入使用
@Component
public class CustomLdapAuthenticationProvider implements AuthenticationProvider {

    private final ActiveDirectoryLdapAuthenticationProvider adProvider;

    // 构造注入
    public CustomLdapAuthenticationProvider(ActiveDirectoryLdapAuthenticationProvider adProvider) {
        this.adProvider = adProvider;
    }

    @Override 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
        return adProvider.authenticate(authentication); 
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
  • 强制使用指定URL:如果不需要AD自动发现,可通过配置关闭该机制,确保Provider只使用你指定的LDAP URL。不过通常保持默认即可,只要DNS解析正常。

3. 检查网络与防火墙

  • 在应用服务器上执行telnet companyDomain 389或nc -zv companyDomain 389(Linux)测试端口连通性。如果连接失败,联系网络管理员开放应用服务器到AD服务器389端口的访问权限。
  • 确认AD服务器的防火墙允许应用服务器的IP访问389端口(LDAP默认端口)。

内容的提问来源于stack exchange,提问作者Bhargava Chandra Dusa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:21:38