2012-04-03 8 views
11

Sono stato bloccato per l'ultimo paio di ore su un fastidioso bit di Active Directory.Errore sconosciuto (0x80005000) con connessione LDAPS

Quello che sto cercando di realizzare è connettersi a un Active Directory tramite LDAP su SSL. Il tipo di autenticazione è anonimo. Sto usando .NET Framework 4.0, C# e Visual Studio 2010.

Il seguente codice dovrebbe funzionare in base alle varie risorse online. Ma continua a venire con l'incredibile auto-esplicativo: 'Unknown Unknown (0x80005000)'.

DirectoryEntry entry = new DirectoryEntry(); 
entry.Path = "LDAPS://some.ldap.server:636"; 
entry.AuthenticationType = AuthenticationTypes.SecureSocketsLayer; 

DirectorySearcher searcher = new DirectorySearcher(); 
searcher.searchRoot = entry; 
searcher.Filter = "(&(objectCategory=person)(objectClass=user))"; 

SearchResultCollection results = searcher.FindAll(); 

Ho semplificato la query effettiva che desidero eseguire rispetto a quella che si trova nel codice. Ma anche con questa query generica (dovrebbe restituire il lavoro su ogni annuncio?) Restituisce l'errore.

+1

'Il tipo di autenticazione è anonimo'. Non lo è, lo si imposta su AuthenticationTypes.SecureSocketsLayer. Che identifica il mittente quindi è meglio impostare anche Username + Password. –

+0

Ciao Hans, Ho provato a connettermi ad AD usando uno strumento chiamato ** JXplorer **. Ha funzionato bene se impostato su SSL e nessun nome utente o password specificati. –

+0

Bene, tieni gli occhi sulla palla. Ricevi ancora E_FAIL quando specifichi un utente valido? Funziona quando si specifica AuthenticationTypes.Anonimo? Se lo fa, sentitevi liberi di supporre che JXplorer faccia qualcosa di simile semplicemente ricadendo su Anonimo o utilizzando le credenziali dell'utente loggato quando non viene specificato alcun utente. –

risposta

13

Finalmente!

Sembra che un'applicazione ASP.NET non disponga dei diritti (o non sappia come) di esaminare l'archivio certificati attendibili a livello macchina. Poiché il certificato era autofirmato, l'applicazione ASP.NET si rifiutava di stabilire una connessione.

Ho risolto il problema utilizzando la convalida del certificato personalizzato. Il seguente codice ha fatto il trucco:

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

Dato che io sono sicuro che il certificato è valido, il metodo ServerCallBack assomiglia a questo:

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

Ma si può sempre naturalmente recuperare il certificato dal locale macchina e convalidarlo.

Lo spazio dei nomi utilizzato in questo esempio è:

System.DirectoryServices.Protocols; 

Questo perché lo spazio dei nomi:

System.DirectoryServices.DirectoryEntry 

non contiene un metodo per la convalida del certificato personalizzato.

Grazie a tutti per il vostro aiuto e il vostro tempo, sperando che questo possa aiutare qualcuno in futuro!

+1

+1, aggiungerò anche per chi viene qui, assicurati di non aver bisogno di credenziali per collegarti al server LDAP, perché potresti. Inoltre, per interrogare ldap dovrai utilizzare le classi SearchRequest e SearchResponse e SearchResponse non ha l'ordinamento, quindi dovrai implementarlo da solo. Ho usato questo non b/c della convalida personalizzata cert ma 'DirectoryEntry' non funzionava in WinPE, non so perché ma questo ha funzionato in modo qualsiasi ... – MDMoore313

+0

È possibile concedere i diritti asp.net per accedere a un cert nell'archivio della macchina aprendo lo snap-in del certificato MMC per l'archivio macchine, trovando il certificato che si desidera utilizzare, fare clic con il tasto destro del mouse su> attività> gestisci chiavi private e concedere il diritto di accesso al servizio di rete. Questo è utile per tutto ciò che utilizza certs, ad es. Identity Foundation, ecc. –

+0

Trovo la tua risposta oggi, ho avuto lo stesso problema. L'eccezione generata non è intuitiva e ha perso molto tempo per trovare questa soluzione. Questo post è molto userfull, +1 o corso. –

2

Per quanto mi ricordo, questo errore indica che c'è un problema con il nome del percorso della directory.

  1. Assicurarsi che "server.domainName" sia il CN nel certificato del server AD.
  2. Assicurarsi che "some.domainName" è ben risolto aggiungere la risoluzione nel vostro file hosts per il test
  3. essere sicuri che il "domainName" è ben risolto aggiungere la risoluzione nel vostro file hosts per il test
  4. Assicurarsi che la chiave pubblica dell'autorità di certificazione che emette il certificato del server sia nell'archivio dell'autorità di certificazione radice attendibile del computer.
  5. provare a fare in questo modo:

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

Salve, il codice funziona senza errori quando lo eseguo nello stesso computer del server Windows; Ma ho bisogno di lavorare con DirectoryEntry dalla macchina remota; In questo caso non funziona; Qualche altra modifica che devo fare? –

+1

"Non funziona" non è abbastanza per me per aiutarti. – JPBlanc

+0

Scusarsi; Sto facendo funzionare lo stesso codice in una macchina remota e ottengo "il server non è operativo" come messaggio di eccezione; Ho trovato che il certificato del server delle vedove non è stato convalidato nella macchina remota; Per convalidare il certificato con l'API 'LdapConnection', il codice è in questo "post, http: //stackoverflow.com/questions/12621256/connect-to-open-ldap-over-ssl"; Il mio requisito è che ho bisogno di convalidare il certificato e utilizzare l'API "DirectoryEntry" come te; –

1

A seconda di come il server di directory (o gli elementi della rete sono configurati) a volte un semplice cambiamento come questo funzionerà (LDAP vs. LDAPS, ma lascia il numero di porta)

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

No; Non funziona –

+1

Mi ha aiutato ma non sono sicuro di quale sia la specifica configurazione AD che causa un simile comportamento. Un altro comportamento interessante è che non funziona quando si fornisce il nome del protocollo LDAP in lettere minuscole nell'URL, ad esempio "LDAP: //some.ldap.server: 636" funziona ma "ldap: //some.ldap.server : 636 "no. Mi sono spaventato particolarmente su questo. – RBT

+0

Anche per me ha funzionato senza impostare la proprietà AuthenticationType sull'oggetto DirectoryEntry su AuthenticationTypes.SecureSocketsLayer ma non sono sicuro che anche questo sarà coerente in tutti gli ambienti e le topologie. – RBT