2012-04-03 19 views
11

Ich habe in den letzten paar Stunden auf einem lästigen Active Directory-Bit stecken.Unbekannter Fehler (0x80005000) mit LDAPS-Verbindung

Was ich versuche zu erreichen, ist eine Verbindung zu einem Active Directory über LDAP über SSL. Der Authentifizierungstyp ist anonym. Ich verwende .NET Framework 4.0, C# und Visual Studio 2010.

Der folgende Code sollte nach verschiedenen Online-Ressourcen funktionieren. Aber es kommt immer wieder mit dem erstaunlichen selbsterklärenden Ergebnis: 'Unbekannter Fehler (0x80005000)'.

Ich habe die eigentliche Abfrage, die ich durchführen möchte, auf die im Code angegebene Abfrage vereinfacht Aber selbst mit dieser generischen Abfrage (es sollte Arbeit an jedem AD zurückgeben?) Gibt es den Fehler zurück.

+1

'Der Authentifizierungstyp ist anonym'. Es ist nicht, Sie legen es auf AuthenticationTypes.SecureSocketsLayer fest. Was den Absender identifiziert, so sollten Sie besser auch Benutzername + Passwort setzen. –

+0

Hallo Hans, Ich habe versucht, Verbindung zu AD mit einem Tool namens ** JXplorer **. Es funktionierte gut, wenn SSL eingestellt war und kein Benutzername oder Passwort angegeben wurde. –

+0

Nun, behalten Sie den Ball im Auge. Erhalten Sie immer noch E_FAIL, wenn Sie einen gültigen Benutzer angeben? Funktioniert es, wenn Sie AuthenticationTypes.Anonymous angeben? Wenn dies der Fall ist, können Sie davon ausgehen, dass JXplorer so etwas wie das Zurückfallen auf Anonymous oder die Verwendung von angemeldeten Benutzeranmeldeinformationen ausführt, wenn kein Benutzer angegeben ist. –

Antwort

13

Endlich!

Es scheint, dass eine ASP.NET-Anwendung nicht über die Rechte verfügt (oder nicht weiß, wie), um den vertrauenswürdigen Zertifikatspeicher auf Maschinenebene zu untersuchen. Da das Zertifikat selbstsigniert war, lehnte die ASP.NET-Anwendung die Herstellung einer Verbindung ab.

Ich habe das Problem mit der benutzerdefinierten Zertifikatsprüfung behoben. Der folgende Code hat den Trick:

LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier("server", port)); 
con.SessionOptions.SecureSocketLayer = true; 
con.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback); 
con.Credential = new NetworkCredential(String.Empty, String.Empty); 
con.AuthType = AuthType.Basic; 
con.Bind(); 

Da ich bin sicher, dass das Zertifikat gültig ist, die ServerCallBack Methode sieht wie folgt aus:

public static bool ServerCallBack(LdapConnection connection, X509Certificate certificate) 
{ 
    return true; 
} 

Aber man kann natürlich immer das Zertifikat aus dem lokalen abrufen Maschine und validiere es.

Der Namespace in diesem Beispiel verwendet wird, ist:

System.DirectoryServices.Protocols; 

Dies liegt daran, dass der Namespace:

System.DirectoryServices.DirectoryEntry 

kein Verfahren für individuelle Zertifikatsüberprüfung enthalten.

Vielen Dank für Ihre Hilfe und Zeit, und hoffentlich wird dies jemandem in der Zukunft helfen!

+1

+1, auch ich werde für jeden hinzufügen, der hier kommt, stellen Sie sicher, dass Sie keine Kredits benötigen, um mit dem LDAP-Server zu verbinden, weil Sie könnten. Um ldap abzufragen, müssen Sie auch die SearchRequest- und SearchResponse-Klassen verwenden, und SearchResponse hat keine Sortierung, so dass Sie diese selbst implementieren müssen. Ich benutze dies nicht b/c der benutzerdefinierten Zertifikatsprüfung, aber 'DirectoryEntry' war in WinPE fehlgeschlagen, weiß nicht warum, aber das funktioniert so was auch immer ... – MDMoore313

+0

Sie können asp.net Rechte auf ein Zertifikat im Maschinenladen zu gewähren Öffnen Sie das Zertifikats-MMC-Snap-In für den Computerspeicher, suchen Sie das gewünschte Zertifikat, klicken Sie mit der rechten Maustaste auf> Tasks> Private Schlüssel verwalten und erteilen Sie dem Netzwerkdienst das Recht zum Lesen. Dies ist nützlich für alles, was certs verwendet, zB Identity Foundation, etc. –

+0

Ich finde deine Antwort heute, ich hatte das gleiche Problem. Die geworfene Ausnahme ist nicht intuitiv und hat viel Zeit verloren, um diese Lösung zu finden. Dieser Beitrag ist sehr nützlich, +1 oder natürlich. –

2

Soweit ich mich erinnere Dieser Fehler bedeutet, dass ein Problem mit dem Verzeichnispfadnamen vorliegt.

  1. Stellen Sie sicher, dass "server.domainName" das CN im Zertifikat Ihres AD-Servers ist.
  2. Seien Sie sicher, dass „some.domainName“ ist gut die Auflösung in der Hosts-Datei für den Test
  3. sicher gelöst hinzufügen sein, dass die „domainname“ aufgelöst wird auch die Auflösung in der Hosts-Datei für den Test hinzufügen
  4. Stellen Sie sicher, dass das öffentliche Schlüssel der Zertifizierungsstelle, die das Serverzertifikat ausstellt, in Ihrem Computer vertrauenswürdiger Stammzertifizierungsstellenspeicher ist.
  5. versuchen, wie dies zu tun:

DirectoryEntry entry = new DirectoryEntry("LDAPS://srventr2.societe.fr:636/DC=societe,DC=fr", "user", "password"); 

DirectorySearcher searcher = new DirectorySearcher(); 
searcher.SearchRoot = entry; 
searcher.SearchScope = SearchScope.Subtree; 
searcher.Filter = "(&(objectCategory=person)(objectClass=user))"; 
SearchResultCollection results = searcher.FindAll(); 
+0

Hallo, der Code funktioniert ohne Fehler, wenn ich es in der gleichen Windows-Server-Maschine ausführen; Aber ich muss mit DirectoryEntry von Remote-Maschine arbeiten; In diesem Fall funktioniert es nicht; Irgendwelche anderen Änderungen, die ich tun muss? –

+1

"Es funktioniert nicht" ist nicht genug für mich, um Ihnen zu helfen. – JPBlanc

+0

Entschuldigung; Ich führe den gleichen Code in einem Remote-Computer und ich bekomme "Server ist nicht betriebsbereit" als Ausnahme Nachricht; Ich habe festgestellt, dass das Witwen-Serverzertifikat auf dem Remote-Computer nicht validiert wurde. Um Zertifikat mit "LdapConnection" API zu validieren, ist Code in diesem "Beitrag, http: //stackoverflow.com/questions/12621256/connect-to-open-ldap-over-ssl"; Meine Anforderung ist, dass ich das Zertifikat validieren und die "DirectoryEntry" API wie Sie verwenden muss; –

1

Je nachdem, wie Verzeichnisserver (oder Elemente in Ihrem Netzwerk konfiguriert sind) manchmal so eine einfache Änderung, wie dies funktionieren wird (LDAP gegen LDAPS, aber Portnummer lassen)

entry.Path = "LDAP://some.ldap.server:636"; 
+0

Nein; Es funktioniert nicht –

+1

Es half mir aber nicht sicher, was ist das spezifische AD-Konfiguration, die ein solches Verhalten verursacht. Ein weiteres interessantes Verhalten ist, dass es nicht funktioniert, wenn Sie den ldap-Protokollnamen in Kleinbuchstaben in der URL eingeben, dh "LDAP: //some.ldap.server: 636" funktioniert, aber "ldap: //some.ldap.server : 636 "nicht. Ich bin extra deswegen ausgeflippt. – RBT

+0

Es funktionierte auch für mich, ohne die AuthenticationType -Eigenschaft für das DirectoryEntry-Objekt auf AuthenticationTypes.SecureSocketsLayer zu setzen, aber ich bin mir nicht sicher, ob dies auch in allen Umgebungen und Topologien konsistent sein wird. – RBT