1

StartTLSを必要とするLDAPサーバーに接続しようとしていますが、運がありません。SessionOptions.StartTransportLayerSecurity(..)を使用するか、SessionOptions.SecureSocketLayerをtrueに設定すると、例外が発生します。

これが私が使用しているコードです:

using (var connection = new LdapConnection(new LdapDirectoryIdentifier(config.LdapServer, config.Port, false, false)))
{
    connection.SessionOptions.ProtocolVersion = 3;
    connection.Credential = new NetworkCredential(config.BindDN, config.BindPassword);
    connection.SessionOptions.VerifyServerCertificate += (conn, cert) => {return true;};
    connection.AuthType = AuthType.Basic;
    //connection.SessionOptions.SecureSocketLayer = true;
    connection.SessionOptions.StartTransportLayerSecurity(null); // throws here, same if done after bind.
    connection.Bind();

    ... do stuff with connection
}

結果として生じる例外は「TlsOperationException:不特定のエラーが発生しました」です。これは、StartTransportLayerSecurityメソッドを呼び出すときに発生します。

OpenLDAPサーバーとActiveDirectoryの両方に対してコードをテストしましたが、どちらも機能しません。

StartTLSをSystem.DirectoryServicesで動作させる方法を知っている人はいますか?

4

3 に答える 3

3

以前は、かなりの量の微妙なLDAPスタックの非互換性がありましたが、これは、顧客が使用している可能性のあるレガシーシナリオにも当てはまる可能性があります。

以下は、OpenLDAPとMicrosoftのLDAPスタックの間の非互換性に関して最も一般的に発生する問題です(より多くの情報が利用可能になったら、これらのリンクを修正および/または置き換えます)

明らかに、OpenLDAPおよび/またはWindows(理想的には両方)を更新すると、これらの問題がここでの原因であることが判明した場合、これらの問題を解決するはずです。

幸運を!

于 2012-01-26T15:15:49.513 に答える
2

このトピックをお読みください: TLS/SSL 暗号化接続を介したバインド

例 19. 基本認証と SSL/TLS を使用してセキュア ポート 50001 で ADAM インスタンスにバインドする

string hostNameAndSSLPort = "sea-dc-02.fabrikam.com:50001";
string userName = "cn=User1,cn=AdamUsers,cn=ap1,dc=fabrikam,dc=com";
string password = "adamPassword01!";

// establish a connection
LdapConnection connection = new LdapConnection(hostNameAndSSLPort);

// create an LdapSessionOptions object to configure session 
// settings on the connection.
LdapSessionOptions options = connection.SessionOptions;

options.ProtocolVersion = 3;

options.SecureSocketLayer = true;

connection.AuthType = AuthType.Basic;

NetworkCredential credential =
        new NetworkCredential(userName, password);

connection.Credential = credential;

try
{
    connection.Bind();
    Console.WriteLine("\nUser account {0} validated using " +
        "ssl.", userName);

    if (options.SecureSocketLayer == true)
    {
        Console.WriteLine("SSL for encryption is enabled\nSSL information:\n" +
        "\tcipher strength: {0}\n" +
        "\texchange strength: {1}\n" +
        "\tprotocol: {2}\n" +
        "\thash strength: {3}\n" +
        "\talgorithm: {4}\n",
        options.SslInformation.CipherStrength,
        options.SslInformation.ExchangeStrength,
        options.SslInformation.Protocol,
        options.SslInformation.HashStrength,
        options.SslInformation.AlgorithmIdentifier);
    }

}
catch (LdapException e)
{
    Console.WriteLine("\nCredential validation for User " +
        "account {0} using ssl failed\n" +
        "LdapException: {1}", userName, e.Message);
}
catch (DirectoryOperationException e)
{
    Console.WriteLine("\nCredential validation for User " +
    "account {0} using ssl failed\n" +
    "DirectoryOperationException: {1}", userName, e.Message);
}

次の例は、「TLS を使用してタスクを認証および実行する方法」を示しています。

string hostOrDomainName = "fabrikam.com";
string userName = "user1";
string password = "password1";

// establish a connection to the directory
LdapConnection connection = new LdapConnection(hostOrDomainName);

NetworkCredential credential =
    new NetworkCredential(userName, password, domainName);

connection.Credential = credential;

connection.AuthType = AuthType.Basic;

LdapSessionOptions options = connection.SessionOptions;

options.ProtocolVersion = 3;

try
{
    options.StartTransportLayerSecurity(null);
    Console.WriteLine("TLS started.\n");
}
catch (Exception e)
{
    Console.WriteLine("Start TLS failed with {0}", 
        e.Message);
    return;
}

try
{
    connection.Bind();
    Console.WriteLine("Bind succeeded using basic " +
        "authentication and SSL.\n");

    Console.WriteLine("Complete another task over " +
        "this SSL connection");
    TestTask(hostName);
}
catch (LdapException e)
{
    Console.WriteLine(e.Message);
}

try
{
    options.StopTransportLayerSecurity();
    Console.WriteLine("Stop TLS succeeded\n");
}
catch (Exception e)
{
    Console.WriteLine("Stop TLS failed with {0}", e.Message);
}

 Console.WriteLine("Switching to negotiate auth type");
 connection.AuthType = AuthType.Negotiate;

 Console.WriteLine("\nRe-binding to the directory");
 connection.Bind();

// complete some action over this non-SSL connection
// note, because Negotiate was used, the bind request 
// is secure. 
// run a task using this new binding
TestTask(hostName);
于 2012-01-24T08:43:05.520 に答える
2

この問題についてもう少し作業した後、いくつかの問題に直面していることに気付きました。

  1. テスト スイートで AD に接続するときに、ポート番号が誤って SSL ポート (636) に変更されるコードにバグがありました (doh!)。
  2. OpenLDAP テスト サーバー (お客様のレプリカ) は openldap-2.4.18 を使用していましたが、これには StartTLS に関する既知の問題があります。

OpenLDAP にパッチを適用した後 (ここで説明されているように - http://www.openldap.org/lists/openldap-bugs/200405/msg00096.html )、#2 を修正することができました - その時点で別のエラーが発生し始めました「ローカルエラーが発生しました。」

もともとこのコードがありましたが:

connection.SessionOptions.VerifyServerCertificate 
    += (conn, cert) => {return true;};

テスト中に削除しましたが、OpenLDAP サーバーが自己署名証明書を使用していたため、信頼できるストアにありませんでした。コールバックを再導入することでこの問題は解決しましたが、現在は構成可能なオプション、つまり「Verify Server Certificate Y/N」になっているため、顧客はチェックをスキップすることを選択する必要があります (主に QA チームが使用するため)。

このソリューションにつながる OpenLDAP バージョンの方向性を教えてくれた Steffen に感謝します。

于 2012-01-26T10:24:39.757 に答える