AD林信任环境下LDAPS跨域查询启用引荐跟踪仍返回referral错误
问题原因排查
- 自动引荐跟踪不支持协议转换:AD域控返回的跨域引荐默认使用
ldap://协议+389端口,你当前连接配置为LDAPS(636端口),默认的自动引荐跟踪不会自动将引荐地址转换为LDAPS协议,导致跟踪请求与现有连接的SSL配置冲突,最终跟踪失败抛出引荐错误。389端口下引荐地址与连接协议匹配,因此可以正常运行。 - 跨域证书信任缺失:你当前的证书校验逻辑仅信任DomainA的LDAPS证书,当自动跟踪到DomainB的LDAPS服务时,DomainB的SSL证书未被运行代码的主机信任,证书校验失败导致引荐跟踪中断。
- 引荐连接的认证配置未继承:默认自动引荐跟踪不会继承你原连接的SSL配置、认证类型、凭证信息,导致到DomainB的引荐连接无法正常完成认证和SSL握手。
解决方法
方法1:手动处理引荐(推荐,稳定性更高)
捕获引荐异常后,解析引荐中的目标域信息,单独建立到DomainB的LDAPS连接执行查询,示例调整后的查询代码:
public static SearchResponse retrieveUserAttributes(string userName, List<string> attributesToReturn, LdapConnection connObj) { try { String filter = "(&(objectCategory=person)(sAMAccountName=" + userName + "))"; String target = "CN=userName,CN=Users,DC=DomainB,DC=local"; SearchRequest searchRequest = new SearchRequest(target, filter, System.DirectoryServices.Protocols.SearchScope.Subtree, attributesToReturn.ToArray()); SearchResponse response = (SearchResponse)connObj.SendRequest(searchRequest); return response; } catch (LdapException ex) when (ex.ErrorCode == 10 /* 引荐错误码 */) { // 单独建立到DomainB的LDAPS连接执行查询 LdapDirectoryIdentifier domainBId = new LdapDirectoryIdentifier("DomainB.local", 636); using LdapConnection domainBConn = new LdapConnection(domainBId, getAdminCredential()) { AuthType = AuthType.Basic, SessionOptions = { ProtocolVersion = 3, SecureSocketLayer = true, VerifyServerCertificate = new VerifyServerCertificateCallback(true) } }; domainBConn.SessionOptions.ReferralChasing = ReferralChasingOptions.All; String filter = "(&(objectCategory=person)(sAMAccountName=" + userName + "))"; String target = "CN=userName,CN=Users,DC=DomainB,DC=local"; SearchRequest searchRequest = new SearchRequest(target, filter, System.DirectoryServices.Protocols.SearchScope.Subtree, attributesToReturn.ToArray()); return (SearchResponse)domainBConn.SendRequest(searchRequest); } catch (Exception exc) { return null; } }
方法2:自定义引荐回调适配LDAPS
如果需要保留自动引荐跟踪逻辑,配置ReferralCallback自定义引荐连接的创建逻辑,自动转换为LDAPS协议,在getLdapsConnection方法中添加如下配置:
connection.SessionOptions.ReferralChasing = ReferralChasingOptions.All; // 新增以下引荐回调配置 connection.SessionOptions.ReferralCallback = new ReferralCallback { GetConnection = (referralUri, ownerConnection) => { // 将引荐的LDAP地址转换为LDAPS UriBuilder uriBuilder = new UriBuilder(referralUri) { Scheme = "ldaps", Port = 636 }; LdapDirectoryIdentifier refIdentifier = new LdapDirectoryIdentifier(uriBuilder.Host, uriBuilder.Port); LdapConnection refConnection = new LdapConnection(refIdentifier, getAdminCredential()) { AuthType = AuthType.Basic, SessionOptions = { ProtocolVersion = 3, SecureSocketLayer = true, VerifyServerCertificate = new VerifyServerCertificateCallback(true) } }; return refConnection; } };
前置检查项
- 确认运行代码的主机已将DomainA、DomainB的LDAPS证书根CA导入到本地计算机的「受信任的根证书颁发机构」存储中,证书的使用者名称/使用者备用名称需与访问的域名完全匹配。
- 确认使用的管理员凭证在DomainB中具备用户属性查询权限,凭证用户名建议使用UPN格式(如
admin@DomainA.local)避免跨域认证失败。 - 确认DomainB的LDAPS 636端口对运行代码的主机网络开放,无防火墙拦截。
内容的提问来源于stack exchange,提问作者Babitha
相关产品推荐
相关产品推荐

