簡體   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