2012-04-03 143 views
11

He estado atrapado durante las últimas horas en un molesto bit de Active Directory.Error desconocido (0x80005000) con la conexión LDAPS

Lo que estoy tratando de lograr es conectarme a un Active Directory a través de LDAP a través de SSL. El tipo de autenticación es anónimo. Estoy usando .NET Framework 4.0, C# y Visual Studio 2010.

El siguiente código debería funcionar de acuerdo con varios recursos en línea. Pero sigue apareciendo con la increíble autoexplicación: 'Error desconocido (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(); 

He simplificado la consulta real que quiero realizar a la que encuentre en el código. Pero incluso con esta consulta genérica (¿debería devolver el trabajo en cada AD?) Devuelve el error.

+1

'El tipo de autenticación es anónimo'. No lo es, lo configuraste en AuthenticationTypes.SecureSocketsLayer. Lo que identifica al remitente, por lo que es mejor que también establezca Nombre de usuario + Contraseña. –

+0

Hola Hans, He intentado conectarme a AD usando una herramienta llamada ** JXplorer **. Funcionó bien cuando se configuró en SSL y no se especificó ningún nombre de usuario o contraseña. –

+0

Bueno, mantén la vista en la pelota. ¿Todavía obtienes E_FAIL cuando especificas un usuario válido? ¿Funciona cuando especifica AuthenticationTypes.Anonymous? Si lo hace, no dude en suponer que JXplorer hace algo así como simplemente recurrir a Anonymous o utilizar las credenciales de usuario registradas cuando no se especifica ningún usuario. –

Respuesta

13

¡Finalmente!

Parece que una aplicación ASP.NET no tiene los derechos (o no sabe cómo) para examinar el almacén de certificados de confianza a nivel de máquina. Como el certificado fue autofirmado, la aplicación ASP.NET se negó a establecer una conexión.

Resolví el problema usando una validación de certificado personalizada. El código siguiente hizo el truco:

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

Desde que estoy seguro de que el certificado es válido, el método ServerCallBack se ve así:

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

Pero se puede recuperar siempre, por supuesto, el certificado del nivel local máquina y validarlo.

El espacio de nombres utilizado en este ejemplo es:

System.DirectoryServices.Protocols; 

Esto es debido a que el espacio de nombres:

System.DirectoryServices.DirectoryEntry 

no contiene un método para la validación del certificado personalizado.

Gracias a todos por su ayuda y tiempo, ¡y espero que esto ayude a alguien en el futuro!

+1

+1, también lo agregaré para cualquiera que venga aquí es asegurarse de que no necesita creds para conectarse al servidor ldap, porque es posible. Además, para consultar ldap, necesitará utilizar las clases SearchRequest y SearchResponse, y SearchResponse no tiene clasificación, por lo que tendrá que implementarlo por su cuenta. Utilicé esto no b/c de la validación de certificados personalizados pero 'DirectoryEntry' estaba fallando en WinPE, no sé por qué pero funcionó así que sea lo que sea ... – MDMoore313

+0

Puede otorgar derechos asp.net para acceder a un certificado en la tienda de máquinas abriendo el complemento mmc del certificado para la tienda de la máquina, buscando el certificado que desea utilizar, haga clic con el botón derecho en> tareas> administrar claves privadas y otorgue el servicio de red leído a la derecha. Esto es útil para cualquier cosa que use certs, por ejemplo, Identity Foundation, etc. –

+0

Hoy encuentro su respuesta, tuve el mismo problema. La excepción lanzada no es intuitiva y se pierde mucho tiempo para encontrar esta solución. Esta publicación es muy útil, +1 o por supuesto. –

2

Por lo que recuerdo Este error significa que hay un problema con el nombre de la ruta del directorio.

  1. Asegúrese de que "server.domainName" es el CN ​​en el certificado de su servidor AD.
  2. Asegúrese de que "some.domainName" está bien resuelto poner la resolución en su archivo de hosts para la prueba
  3. Asegúrese de que el "domainname" está bien resuelto poner la resolución en su archivo de hosts para la prueba
  4. Asegúrese de que el ke público de la autoridad de certificación que emite el certificado del servidor se encuentre en la tienda de autoridad de certificación raíz de confianza de su computadora.
  5. trate de hacer de esta manera:

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

Hola, el código funciona sin errores cuando lo ejecuto en la misma máquina del servidor de Windows; Pero necesito trabajar con DirectoryEntry desde la máquina remota; En este caso, no funciona; ¿Algún otro cambio que deba hacer? –

+1

"No funciona" no es suficiente para ayudarlo. – JPBlanc

+0

Disculpa; Estoy ejecutando el mismo código en una máquina remota y recibo el mensaje "El servidor no funciona" como mensaje de excepción; Descubrí que el certificado del servidor de viudas no está validado en la máquina remota; Para validar el certificado con la API 'LdapConnection', el código se encuentra en esta "publicación, http: //stackoverflow.com/questions/12621256/connect-to-open-ldap-over-ssl"; Mi requisito es que necesito validar el certificado y hacer uso de API "DirectoryEntry" igual que usted; –

1

Dependiendo de cómo el servidor de directorio (o elementos de la red se ha configurado) a veces un simple cambio como esto va a funcionar (LDAP vs LDAPS pero deje el número de puerto)

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

No; No funciona –

+1

Me ayudó pero no estoy seguro de cuál es esa configuración AD específica que causa dicho comportamiento. Otro comportamiento interesante es que no funciona cuando se da el nombre del protocolo ldap en minúsculas en la URL, es decir, "LDAP: //some.ldap.server: 636" funciona pero "ldap: //some.ldap.server : 636 "no. Me asusté especialmente por esto. – RBT

+0

También funcionó para mí sin establecer la propiedad AuthenticationType en el objeto DirectoryEntry en AuthenticationTypes.SecureSocketsLayer, pero no estoy seguro de si esto será uniforme en todos los entornos y topologías. – RBT

Cuestiones relacionadas