2012-04-03 20 views
11

Utknąłem przez kilka ostatnich godzin na irytującym kodzie Active Directory.Nieznany błąd (0x80005000) z połączeniem LDAPS

Próbuję osiągnąć połączenie z Active Directory przez LDAP przez SSL. Typ uwierzytelnienia jest anonimowy. Korzystam z .NET Framework 4.0, C# i Visual Studio 2010.

Poniższy kod powinien działać zgodnie z różnymi zasobami online. Ale wciąż wymyśla niesamowite: "Nieznany błąd (0x80005000)".

Uprościliśmy rzeczywiste zapytanie, które chcę wykonać, do tego, które znajduje się w kodzie. Ale nawet z tą ogólną kwerendą (powinna powrócić do pracy przy każdym AD?) Zwraca błąd.

+1

"Typ uwierzytelnienia jest anonimowy". Nie jest, ustawiasz go na AuthenticationTypes.SecureSocketsLayer. Który identyfikuje nadawcę, aby lepiej ustawić również nazwę użytkownika i hasło. –

+0

Witaj Hans, Próbowałem połączyć się z AD za pomocą narzędzia o nazwie ** JXplorer **. Po ustawieniu na SSL nie działała żadna nazwa użytkownika ani hasło. –

+0

Cóż, miej oczy na piłce. Czy nadal otrzymujesz E_FAIL po określeniu prawidłowego użytkownika? Czy to działa, gdy określasz AuthenticationTypes.Anonymous? Jeśli tak, to możesz założyć, że JXplorer robi coś podobnego po prostu przechodząc z powrotem do anonimowego lub używając zalogowanych poświadczeń użytkownika, gdy żaden użytkownik nie jest określony. –

Odpowiedz

13

Wreszcie!

Wygląda na to, że aplikacja ASP.NET nie ma uprawnień (lub nie wie jak) do sprawdzenia zaufanego magazynu certyfikatów na poziomie komputera. Ponieważ certyfikat był samopodpisany, aplikacja ASP.NET odmówiła nawiązania połączenia.

Naprawiłem problem za pomocą niestandardowego sprawdzania poprawności certyfikatu. Poniższy kod wystarczyły:

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

Ponieważ jestem pewien, że certyfikat jest ważny, metoda ServerCallBack wygląda tak:

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

Ale zawsze można oczywiście pobrać certyfikat z lokalnego maszynę i zatwierdź ją.

Przestrzeń nazw stosowany w tym przykładzie:

System.DirectoryServices.Protocols; 

To dlatego przestrzeni nazw:

System.DirectoryServices.DirectoryEntry 

nie zawiera metodę uwierzytelniania certyfikatu zwyczaj.

Dziękuję wszystkim za pomoc i czas, i mam nadzieję, że to pomoże komuś w przyszłości!

+1

+1, również dodam dla każdego, kto tu przychodzi, upewnij się, że nie potrzebujesz do łączenia się z serwerem LDAP, ponieważ możesz. Ponadto do zapytania ldap będziesz potrzebował użyć klas SearchRequest i SearchResponse, a SearchResponse nie ma sortowania, więc będziesz musiał zaimplementować to samemu. Użyłem tego nie b/c niestandardowego sprawdzania poprawności certyfikatu, ale 'DirectoryEntry' zawodzi w WinPE, nie wiem dlaczego, ale to działało, więc cokolwiek ... – MDMoore313

+0

Możesz udzielić praw do asp.netu dostępu do certyfikatu w magazynie maszyny otwierając przystawkę mmc certyfikatu dla magazynu maszynowego, znajdując certyfikat, którego chcesz użyć, kliknij prawym przyciskiem myszy> zadania> zarządzaj kluczami prywatnymi i nadaj usługę sieciową odczytywaną w prawo. Jest to przydatne dla wszystkiego, co używa certyfikatów, np. Identity Foundation, itp. –

+0

Znajduję dziś odpowiedź, miałem ten sam problem. Wyrzucony wyjątek nie jest intuicyjny i stracił wiele czasu na znalezienie tego rozwiązania. Ten wpis jest bardzo użyteczny, +1 lub oczywiście. –

2

O ile pamiętam, ten błąd oznacza, że ​​wystąpił problem z nazwą ścieżki do katalogu.

  1. Upewnij się, że "server.domainName" jest CN w certyfikacie serwera AD.
  2. Pamiętaj, że „some.domainName” jest dobrze rozwiązany dodać rozdzielczość w swoim pliku hosts do testu
  3. Pamiętaj, że „domainName” jest dobrze rozwiązany dodać rozdzielczość w swoim pliku hosts do testu
  4. Upewnij się, że publiczny klucz urzędu certyfikacji wystawiającego certyfikat serwera znajduje się w zaufanym głównym urzędzie certyfikacji komputera.
  5. spróbować zrobić tak:

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

Witaj, kod działa bez błędów, gdy uruchomię go na tym samym komputerze z systemem Windows; Ale muszę pracować z DirectoryEntry z komputera zdalnego; W tym przypadku nie działa; Jakieś inne zmiany, które muszę zrobić? –

+1

"Nie działa" to dla mnie za mało, aby ci pomóc. – JPBlanc

+0

Przeproś; Używam tego samego kodu na zdalnym komputerze i otrzymuję komunikat "Serwer nie działa" jako komunikat wyjątku; Zauważyłem, że certyfikat serwera wdów nie jest sprawdzany na zdalnym komputerze; Aby zweryfikować certyfikat za pomocą API "LdapConnection", kod znajduje się w tym "post, http: //stackoverflow.com/questions/12621256/connect-to-open-ldap-over-ssl"; Moim wymaganiem jest potwierdzenie ważności certyfikatu i korzystanie z API "DirectoryEntry" takiego samego jak Ty; –

1

zależności od konfiguracji serwera katalogów (lub elementy w sieci są skonfigurowane) czasami prosta zmiana takich jak to będzie działać (LDAP vs. LDAPS, ale zostaw numer portu)

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

Nie; To nie działa –

+1

Pomogło mi to, ale nie jestem pewien, jaka to konkretna konfiguracja AD, która powoduje takie zachowanie. Innym ciekawym zachowaniem jest to, że nie działa, gdy podajesz nazwę protokołu LDAP małymi literami w adresie URL, np. "LDAP: //some.ldap.server: 636" działa, ale "ldap: //some.ldap.server : 636 "nie. Zwariowałem na tym specjalnie. – RBT

+0

Również zadziałało dla mnie bez ustawiania właściwości AuthenticationType na obiekcie DirectoryEntry na AuthenticationTypes.SecureSocketsLayer, ale nie jestem pewien, czy nawet to będzie spójne we wszystkich środowiskach i topologiach. – RBT

Powiązane problemy