2012-01-18 3 views
1

J'essaye de me connecter à un serveur LDAP qui nécessite StartTLS, mais qui n'a pas de chance - chaque fois que j'utilise SessionOptions.StartTransportLayerSecurity (..) ou que SetOptions.SecureSocketLayer a la valeur true, J'ai des exceptions.Utilisation de StartTLS avec LDAP à partir de System.DirectoryServices

Voici le code que je utilise:

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 
} 

L'exception résultant est « TlsOperationException: Une erreur non spécifiée est produite », ce qui se produit lors de l'appel de la méthode StartTransportLayerSecurity.

J'ai testé le code par rapport au serveur OpenLDAP et à Active Directory, mais cela ne fonctionne pas.

Est-ce que quelqu'un sait comment faire fonctionner StartTLS avec System.DirectoryServices?

+3

Pourriez-vous spécifier les versions spécifiques d'OpenLDAP, d'Active Directory et en particulier les systèmes d'exploitation pour * client * et serveur impliqués ici pour affiner la portée? Il y avait une bonne quantité d'incompatibilités subtiles de pile LDAP dans la nature, ce qui pourrait encore s'appliquer au scénario potentiellement hérité que votre client pourrait utiliser. –

+1

Salut Steffen, info était OpenLDAP 2.4.18, FreeBSD pour le serveur et le client était une machine Windows Server 2008 r2 (le code client est hébergé dans une application ASP.Net, .Net Framework 3.5 SP1). En cherchant un peu plus loin sur la version de LDAP m'a conduit à quelques articles de blog sur le sujet, y compris: http://pongo15.wordpress.com/2009/12/18/on-getting-openldap-and-windows- ldap-to-interop/- ce qui m'a aidé à aller au fond du problème. Je vais essayer d'encourager l'utilisateur à passer au dernier OpenLDAP car je suppose que ce problème est probablement corrigé dans les versions ultérieures (leur version est vraiment ancienne, publiée le 6 septembre 2009) – Bittercoder

+0

Merci pour les informations de suivi, ce qui aidera les lecteurs plus tard concernant des problèmes comme celui-ci (+1)! J'ai [mis à jour ma réponse] (http://stackoverflow.com/posts/9020311/revisions#) en conséquence ... –

Répondre

1

Après un peu plus de travail sur cette question, je trouve que je courais jusqu'à agains t deux questions:

  1. Il y avait un bug dans le code où le numéro de port a été incorrectement changé au port SSL (636) lors de la connexion à AD dans notre suite de tests (doh!).
  2. Le serveur de test OpenLDAP (qui était une réplique de nos clients) utilisait openldap-2.4.18, qui a rencontré des problèmes avec StartTLS.

Après l'application d'un patch pour OpenLDAP (comme discuté ici - http://www.openldap.org/lists/openldap-bugs/200405/msg00096.html) nous avons pu fixer # 2 - à quel point nous avons commencé à une autre erreur « Une erreur locale a eu lieu ».

Bien qu'à l'origine nous avions ce code: il

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

Nous avions retiré lors du test, et parce que le serveur OpenLDAP utilisait un certificat auto-signé, ce n'était pas dans un magasin de confiance. La réintroduction du rappel a permis de résoudre ce problème, bien que nous en fassions maintenant une option configurable, à savoir «Vérifier le certificat du serveur O/N», de sorte que les clients doivent choisir de ne pas utiliser le chèque.

Merci Steffen de m'avoir orienté vers les versions d'OpenLDAP qui m'ont conduit à cette solution.

+0

Merci pour le résumé détaillé de vos résultats (+1) - J'ai aussi appris quelque chose, à savoir afficher immédiatement mes résultats de recherche afin d'éviter les doublons (après tout, les réponses peuvent être affinées à tout moment) et faire en sorte que la recherche d'enjeux intéressants avec des généreuses généreux comme la vôtre soit encore plus valable! J'ai [élargi mon commentaire comme une réponse] (http://stackoverflow.com/a/9020311/45773) maintenant en conséquence pour se familiariser avec cette approche - merci beaucoup;) –

1

S'il vous plaît lire ce sujet: Binding over a TLS/SSL Encrypted Connection

Exemple 19. La liaison à une instance ADAM sur 50001 port sécurisé en utilisant l'authentification de base et SSL/TLS

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

Et le prochain spectacle exemple « Comment utiliser TLS pour authentifier et effectuer une tâche »

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

Il y avait une bonne quantité d'incompatibilités subtiles de pile LDAP dans la nature, ce qui pourrait encore s'appliquer au scénario potentiellement hérité que votre client pourrait utiliser.

Voici les problèmes les plus fréquemment rencontrés concernant les incompatibilités entre la pile LDAP OpenLDAP et Microsoft (je vais modifier et/ou remplacer ces liens une fois de plus d'information est disponible) :

De toute évidence, la mise à jour soit OpenLDAP et/ou Windows (idéalement à la fois bien sûr) devraient remédier à ces problèmes, si elles se révèlent être le coupable ici.

Bonne chance!

Questions connexes