繁体   English   中英

TLS 1.2 适用于 LdapConnection 但不适用于 DirectoryEntry

[英]TLS 1.2 works with LdapConnection but not DirectoryEntry

我无法使用 DirectoryService 类通过 TLS 1.2 连接到 Active Directory。 我能够通过 Windows 上的 LDP、Windows 上的开源 LDAPAdmin 和 .Net 4.7.2 控制台应用程序中的 LdapConnection 使用 TLS 1.2 进行连接。 我已经使用 WireShark 验证了 TLS 1.2 连接。 这是一些示例代码:

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");

    // Is not 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}");
    }

    //Does not work
    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}");
    }

    //Does not work
    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}");
    }

    //Does not work
    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 类进行连接? 我在 StackOverflow 中似乎有很多关于这个主题的问题,这就是为什么我在示例代码中包含了我读到的所有其他答案。

通过 LDAPS 与DirectoryEntry连接的正确方法是:

e = new DirectoryEntry("LDAP://server.domain.com:636", "user@domain.com", "password");

您不需要指定AuthenticationTypes.SecureSocketsLayer ,因为这是连接端口 636 的唯一可能方式,但如果您这样做也不会造成任何伤害。

我的猜测是您的证书有问题。 可能是以下两个原因之一:

  1. 证书上的域名与您用于连接的域名不匹配。 例如,如果您使用域名server.domain.com进行连接,则证书必须颁发给server.domain.com (或具有主题备用名称)。 如果证书上的域只是domain.com ,或者只是server ,那么它不匹配并且会失败。
  2. 该证书不是由客户端计算机信任的机构颁发的。 例如,它可以是自签名的。

它适用于LdapConnection因为你有这个:

op.VerifyServerCertificate = (ldapConnection, serverCertificate) =>
{
    return true;
};

这是您用于验证证书的自定义代码,它始终返回true 因此,证书的任何问题都将被忽略。 DirectoryEntry没有为您提供执行此操作的方法。

您可以使用此答案中的 PowerShell 代码下载证书(确保更改域名)并检查它。 当您双击 .cer 文件时,Windows 将标记它的问题(如果有)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM