2010-08-26 28 views
15

Estoy intentando utilizar la biblioteca .NET System.DirectoryServices.AccountManagement para obtener el UserPrincipal para un usuario particular de Active Directory.UserPrincipal.FindByIdentity Permisos

Tengo el siguiente código:

PrincipalContext context = new PrincipalContext(ContextType.Domain, "DomainName"); 
userPrincipal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username); 

Este código se ejecuta como un usuario de dominio válido, pero cuando lo ejecuto me da la siguiente excepción:

System.DirectoryServices. DirectoryServicesCOMException (0x8007052E): Error de inicio de sesión: nombre de usuario desconocido o contraseña incorrecta.

Lo que es interesante es que puedo hacer la siguiente llamada, utilizando el mismo contexto, sin ningún problema:

context.ValidateCredentials(username, password, ContextOptions.Negotiate) 

ideas?

+0

Comprobar esta respuesta: http://stackoverflow.com/questions/1863801/findbyidentity-failing-with-pricipaloperationexception-in-asp-net-webapp/3515280#3515280 –

Respuesta

12

Necesita usar el constructor PrincipalContext que lleva el nombre de usuario y la contraseña.

El motivo por el que Validate funciona es porque está usando las credenciales proporcionadas para enlazar al directorio.

+0

Esto no significa tiene mucho sentido para mí. ¿Está diciendo que la llamada ValidateCredentials usa las credenciales de identidad actuales, pero la llamada UserPrincipal.FindByIdentity, que acepta el contexto en cuestión, no? Si ese es el caso, ¿cómo hago para usar la identidad actual (como en, la identidad del hilo) para hacer la llamada? No tengo un nombre de usuario o contraseña para aprobar, ya que esta es una aplicación que se ejecuta como una configuración de cuenta de servicio en el momento de la instalación. No puedo almacenar estas credenciales en ningún lado. – RMD

+0

Creo que no entendió, ValidateCredentials usa las credenciales provistas en la lista de parámetros para ValidateCredentials: el contexto que ha definido no tiene credenciales asociadas además de las del hilo actual. Sospecho que tus problemas están en la configuración/implementación del servidor. Asegúrese de que la cuenta que ejecuta el servicio haya sido delegada dentro del dominio. – Nate

+0

Sí, lo malentendí. El usuario del subproceso actual es definitivamente un usuario de dominio válido. Cuando dice "delegado dentro del dominio", ¿a qué se refiere exactamente? – RMD

3

Parece que tiene una credencial de red almacenada. En Windows, puede especificar el uso de credenciales de red diferentes cuando intente llegar a los recursos de una red. Puedo reproducir exactamente el mismo problema que está viendo al configurar una credencial de red incorrecta.

Suponiendo que su dominio se llama yourdomain.com, puede indicarle a Windows que use siempre un nombre de usuario y una contraseña específicos siempre que hable con cualquier equipo que tenga sudominio.com.

=== === 7/2008 de Windows

  1. lanzamiento del "Crendentail Manager".
  2. En virtud del artículo credenciales de Windows, haga clic en Add a Windows credentials
  3. En dirección de red, puesto en *.yourdomain.com
  4. En nombre de usuario y contraseña, poner en un nombre de usuario incorrecto o una contraseña incorrecta

=== Windows XP/2000/2003 ===

  1. Haga clic en Inicio y Ejecutar
  2. Type en control keymgr.dll
  3. Haga clic en el botón Añadir en "nombres almacenados de usuario y contraseñas" diálogo
  4. En el cuadro de texto Servidor, poner en *.yourdomain.com
  5. En nombre de usuario y contraseña, poner el nombre de usuario incorrecto o una contraseña incorrecta

Si esto es realmente el problema al que se enfrenta, la solución más fácil es eliminar las contraseñas almacenadas.

¿Por qué funciona context.ValidateCredentials (nombre de usuario, contraseña, ContextOptions.Negotiate)?Es simplemente porque está inicializando otra autenticación Kerberos/NTLM dado que proporciona uername y password nuevamente. Debajo del capó, si se elige Kerberos, se le enviaría al controlador de dominio el nombre de usuario y la contraseña provistos y se cambiaría por un vale TGT de Kerberos. Luego, su máquina obtiene un ticket de servicio en el servidor LDAP usando este ticket TGT. Luego, su máquina enviará este ticket de servicio al servidor LDAP. Tenga en cuenta que este ticket de servicio no se conservará en la sesión de inicio de sesión actual.

¿Por qué UserPrincipal.FindByIdentity no funciona? Si no tiene ninguna contraseña almacenada, normalmente debería funcionar porque Windows solo usará el ticket TGT actual del usuario de inicio de sesión para intercambiar el ticket de servicio del servidor LDAP. No hay un proceso de validación de nombre de usuario/contraseña involucrado. Sin embargo, si tiene una contraseña de usuario incorrecta, Windows pensaría que no debería usar el ticket TGT actual para el usuario de inicio de sesión. En cambio, debería obtener un nuevo boleto TGT usando la contraseña de red almacenada. Esa es la razón por la que está viendo System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.

+0

Interesante. Este código se ejecuta desde el contexto de una aplicación ASP.NET, por lo que no creo que las contraseñas almacenadas hagan la diferencia. Verificare si estás en lo correcto. – RMD

+0

@RMD Ah, te perdiste esta información. ¿Estás usando Autenticación de Windows? ¿O simplemente está utilizando la cuenta de servicio local para acceder al AD? –

+0

Como dije en mi publicación original: "Este código se está ejecutando como un usuario de dominio válido". – RMD