TLS 1.2可通过LdapConnection连接AD,但DirectoryEntry无法实现
如何通过DirectoryService类使用TLS 1.2连接Active Directory?
我能够通过Windows LDP工具、开源LDAPAdmin工具,以及.NET 4.7.2控制台应用中的LdapConnection类成功建立TLS 1.2连接到Active Directory(已通过WireShark验证连接有效性),但使用DirectoryService类的DirectoryEntry尝试多种配置均失败,示例代码如下:
static void Main(string[] args) { LdapConnection conn = new LdapConnection("server.domain.com:636"); var op = conn.SessionOptions; op.ProtocolVersion = 3; op.SecureSocketLayer = true; op.VerifyServerCertificate = (ldapConnection, serverCertificate) => { return true; }; conn.AuthType = AuthType.Negotiate; var cred = new NetworkCredential("user@domain.com", "password"); conn.Credential = cred; conn.Bind(cred); Console.WriteLine("LdapConnection Success"); // 未使用TLS 1.2 var de = new DirectoryEntry("LDAP://server.domain.com", "user@domain.com", "password", AuthenticationTypes.Secure); try { foreach (var child in de.Children) { Console.WriteLine(child); } Console.WriteLine($"{de.Path} Success"); } catch (Exception ex) { Console.WriteLine($"{de.Path} {ex.Message}"); } // 连接失败 de = new DirectoryEntry("LDAP://server.domain.com:636", "user@domain.com", "password"); try { foreach (var child in de.Children) { Console.WriteLine(child); } Console.WriteLine($"{de.Path} Success"); } catch (Exception ex) { Console.WriteLine($"{de.Path} {ex.Message}"); } // 连接失败 de = new DirectoryEntry("LDAP://server.domain.com", "user@domain.com", "password", AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.Secure); try { foreach (var child in de.Children) { Console.WriteLine(child); } Console.WriteLine($"{de.Path} Success"); } catch (Exception ex) { Console.WriteLine($"{de.Path} {ex.Message}"); } // 连接失败 de = new DirectoryEntry("LDAP://server.domain.com:636", "user@domain.com", "password", AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.Secure); try { foreach (var child in de.Children) { Console.WriteLine(child); } Console.WriteLine($"{de.Path} Success"); } catch (Exception ex) { Console.WriteLine($"{de.Path} {ex.Message}"); } Console.ReadKey(); }
已参考相关问题并尝试多种方案均无效,请问如何通过DirectoryService类实现TLS 1.2连接?
解决方案
1. 强制代码使用TLS 1.2协议
.NET 4.7.2虽支持自动检测TLS版本,但DirectoryEntry底层可能未正确触发该逻辑,需在代码开头强制指定TLS 1.2:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
2. 调整DirectoryEntry的认证参数
确保同时指定SecureSocketsLayer和Secure认证类型,且明确使用636端口,修改后的连接代码如下:
var de = new DirectoryEntry("LDAP://server.domain.com:636", "user@domain.com", "password", AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.Secure); try { // 主动触发连接(访问属性会强制建立连接) var entryName = de.Name; foreach (var child in de.Children) { Console.WriteLine(child); } Console.WriteLine($"{de.Path} Success"); } catch (Exception ex) { Console.WriteLine($"{de.Path} {ex.Message}"); }
3. 检查系统Schannel配置
若上述代码仍失败,需确保客户端Windows系统已启用TLS 1.2并禁用旧版本协议:
- 打开注册表编辑器,定位到
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client - 创建/修改以下DWORD值:
Enabled=1DisabledByDefault=0
- 重启系统使配置生效
4. 处理证书信任问题
DirectoryEntry没有类似LdapConnection的证书验证回调,若AD服务器使用自签名或未受信任证书,需将证书导入客户端的受信任根证书颁发机构存储,否则连接会因证书验证失败被拒绝。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

