2009-08-25 15 views
8

¿Cuál es la forma más simple y más eficiente en C# para verificar si existe un nombre de cuenta de usuario de Windows? Esto es en un entorno de dominio.¿Cómo comprobar si el nombre de la cuenta de usuario de Windows existe en el dominio?

  • de entrada: nombre de usuario en [dominio]/[usuario] formato (por ejemplo, "miempresa \ bob")
  • Salida: Verdadero si existe el nombre de usuario, falso en caso contrario.

he encontrado this article pero los ejemplos no están relacionados con la autenticación y la manipulación de las cuentas de usuario, y se supone que ya tiene un nombre completo del usuario, mientras que yo estoy empezando con el nombre de cuenta de usuario.

Estoy seguro de que puedo resolver esto usando AD, pero antes de hacerlo me preguntaba si existe una API de nivel superior que haga lo que necesito.

* ACTUALIZACIÓN *

Probablemente hay muchas maneras de hacer esto, Russ registró una que podría funcionar, pero no pude encontrar la manera de ajustar para que funcione en mi entorno. Lo que encontrar un enfoque diferente, utilizando el proveedor de WinNT que hizo el trabajo para mí:

public static bool UserInDomain(string username, string domain) 
    { 
     string path = String.Format("WinNT://{0}/{1},user", domain, username); 

     try 
     { 
      DirectoryEntry.Exists(path); 
      return true; 
     } 
     catch (Exception) 
     { 
      // For WinNT provider DirectoryEntry.Exists throws an exception 
      // instead of returning false so we need to trap it. 
      return false; 
     } 
    } 

P. S. Para aquellos que no están familiarizados con la API utilizada anteriormente: debe agregar una referencia a System.DirectoryServices para usarla.

El enlace que encontré me ayudó con esto: How Can I Get User Information Using ADSI Los ejemplos usan ADSI pero también se pueden aplicar a .NET DirectoryServices. También demuestran otras propiedades del objeto de usuario que pueden ser útiles.

+0

amor la nueva versión, super rápida y exactamente lo que necesitaba ¡Gracias! –

Respuesta

4

El espacio de nombre System.DirectoryServices en el artículo es exactamente lo que necesita y está destinado para este fin. Si no recuerdo mal, es una envoltura alrededor de las interfaces COM Active Directory Server Interfaces

EDIT:

Algo parecido a lo que sigue debe hacerlo (que probablemente podría hacer con un poco de control y manipulación). Utilizará el dominio del contexto de seguridad actual para encontrar un controlador de dominio, pero esto podría modificarse fácilmente para pasar en un servidor designado.

public bool UserInDomain(string username, string domain) 
{ 
    string LDAPString = string.Empty; 
    string[] domainComponents = domain.Split('.'); 
    StringBuilder builder = new StringBuilder(); 

    for (int i = 0; i < domainComponents.Length; i++) 
    { 
     builder.AppendFormat(",dc={0}", domainComponents[i]); 
    } 
    if (builder.Length > 0) 
     LDAPString = builder.ToString(1, builder.Length - 1); 

    DirectoryEntry entry = new DirectoryEntry("LDAP://" + LDAPString); 

    DirectorySearcher searcher = new DirectorySearcher(entry); 

    searcher.Filter = "sAMAccountName=" + username; 

    SearchResult result = searcher.FindOne(); 

    return result != null; 
} 

y probado con el siguiente

Console.WriteLine(UserInDomain("username","MyDomain.com").ToString()); 
+0

Esas API de propósito general para acceder a la información de Active Directory (como ADO.NET para datos de SQL). El desafío de la programación AD es comprender el esquema y construir las consultas correctas para obtener la información que necesita (y hay mucha información almacenada en AD). – DSO

+0

@DSO: tiene el dominio y el nombre de usuario, por lo que debería poder utilizar un objeto DirectorySearcher para encontrar si el nombre de usuario existe en ese dominio instanciando el objeto DirectorySearcher y pasando un objeto DirectoryEntry vinculado al nodo que representa el objeto de dominio –

+0

Su ejemplo no funcionó, recibo un error de "servidor devuelto por referencia", que creo que significa que el contenedor no existe. Creo que tienes razón, en principio, para unir primero el contenedor correcto y luego buscar el objeto, así que te di un voto positivo para eso. Sin embargo, no creo que su enfoque para construir la consulta para enlazar al dominio funcione en todos los entornos. Encontré una solución más simple (publicación actualizada). – DSO

2

encontrado una manera simple de hacer esto si estás en una versión de alta marco suficiente:

using System.DirectoryServices.AccountManagement; 

bool UserExists(string userName, string domain) { 
    using (var pc = new PrincipalContext(ContextType.Domain, domain)) 
    using (var p = Principal.FindByIdentity(pc, IdentityType.SamAccountName, userName)) { 
     return p != null; 
    } 
} 
Cuestiones relacionadas