Pregunta

Estoy usando el siguiente código en Windows Vista Ultimate SP1 para consultar nuestro servidor de directorio activo para verificar el nombre de usuario y la contraseña de un usuario en un dominio.

public Object IsAuthenticated()
{
    String domainAndUsername = strDomain + "\\" + strUser;
    DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, strPass);
    SearchResult result;
    try
    {
        //Bind to the native AdsObject to force authentication.         

        DirectorySearcher search = new DirectorySearcher(entry) { Filter = ("(SAMAccountName=" + strUser + ")") };

        search.PropertiesToLoad.Add("givenName"); // First Name                
        search.PropertiesToLoad.Add("sn"); // Last Name
        search.PropertiesToLoad.Add("cn"); // Last Name

        result = search.FindOne();

        if (null == result)
        {
            return null;
        }

        //Update the new path to the user in the directory.
        _path = result.Path;
        _filterAttribute = (String)result.Properties["cn"][0];
    }
    catch (Exception ex)
    {
        return new Exception("Error authenticating user. " + ex.Message);
    }
    return user;
}

el destino está utilizando .NET 3.5 y compilado con el estándar VS 2008

Estoy registrado en una cuenta de dominio que es un administrador de dominio donde se ejecuta la aplicación.

El código funciona perfectamente en Windows XP; pero obtengo la siguiente excepción cuando la ejecuto en Vista:

System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.

   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
   at System.DirectoryServices.DirectorySearcher.FindOne()
   at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated()
   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
   at System.DirectoryServices.DirectorySearcher.FindOne()
   at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated()

He intentado cambiar los tipos de autenticación, no estoy seguro de lo que está pasando.


Vea también : ¿Validar un nombre de usuario y contraseña en Active Directory?

¿Fue útil?

Solución

Si estás usando .net 3.5, usa este código en su lugar.

Para autenticar a un usuario:

PrincipalContext adContext = new PrincipalContext(ContextType.Domain);

using (adContext)
{
     return adContext.ValidateCredentials(UserName, Password);
}

Si necesita encontrar el usuario para los atributos de R / W al objeto, haga esto:

PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal foundUser = 
    UserPrincipal.FindByIdentity(context, "jdoe");

Esto está usando el espacio de nombres System.DirectoryServices.AccountManagement, por lo que deberá agregarlo a sus declaraciones de uso.

Si necesita convertir un objeto UserPrincipal en un objeto DirectoryEntry para trabajar con código heredado, puede hacer esto:

DirectoryEntry userDE = (DirectoryEntry)foundUser.GetUnderlyingObject();

Otros consejos

Encontré ese mismo código flotando en Internet en varios sitios web y no me funcionó. Steve Evans probablemente tenga razón en que si estás en .NET 3.5, no deberías usar este código. Pero si aún ESTÁ en .NET 2.0, puede intentar esto para autenticar sus servicios de AD:

DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, 
   userName, password, 
   AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer);
object nativeObject = entry.NativeObject;

La primera línea crea un objeto DirectoryEntry con dominio, nombre de usuario y contraseña. También establece los AuthenticationTypes. Observe cómo estoy configurando tanto la autenticación segura (Kerberos) como la SSL mediante el comando " Bitwise OR " ('|') operador entre los dos parámetros.

La segunda línea fuerza el objeto NativeObject de la entrada " " Para enlazar a los servicios de AD utilizando la información de la primera línea.

Si se lanza una excepción, las credenciales (o las configuraciones) eran malas. Si no hay excepción, estás autenticado. El mensaje de excepción usualmente indicará lo que salió mal.

Este código es bastante similar al que ya tienes, pero el dominio se usa donde tienes " ruta " ;, y el nombre de usuario no se combina con el dominio. Asegúrese de establecer sus tipos de autenticación correctamente también. Esto puede hacer o deshacer la capacidad de autenticación.

De todos modos, lo descubrí. Si pasas el dominio con el nombre de usuario en Vista, no funciona como " dominio \ usuario " así que simplemente pasando " usuario " en su lugar, parece funcionar bien, excepto que tienes que estar en el mismo dominio

¿La vinculación a LDAP requiere privilegios elevados (UAC)? Puede intentar ejecutar Visual Studio y / o la aplicación como Administrador y ver si eso ayuda. Si ese es el problema, siempre podría agregar un manifiesto a la aplicación y configurarlo para que requiera una elevación, de esta forma, se le indicará cuando un usuario lo ejecute.

No estoy seguro de por qué requeriría privilegios elevados, pero vale la pena intentarlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top