2009-08-25 5 views
8

Quel est le moyen le plus simple et le plus efficace en C# de vérifier si un nom de compte d'utilisateur Windows existe? C'est dans un environnement de domaine.Comment vérifier si le nom de compte d'utilisateur Windows existe dans le domaine?

  • Entrée: nom d'utilisateur dans [domaine]/[utilisateur] le format (par exemple "mycompany \ bob")
  • Sortie: Vrai si le nom d'utilisateur existe, false sinon.

Je n'ai trouvé this article mais les exemples y sont liés à l'authentification et la manipulation des comptes d'utilisateurs, et ils supposent que vous avez déjà un nom d'utilisateur distingué, alors que je commence avec le nom du compte utilisateur.

Je suis sûr que je peux comprendre cela en utilisant AD, mais avant que je le fais, je me demandais s'il y a une simple API de plus haut niveau qui fait ce dont j'ai besoin.

* MISE À JOUR *

Il y a probablement plusieurs façons de faire, Russ a affiché qui pourrait fonctionner, mais je ne pouvais pas comprendre comment modifier à travailler dans mon environnement. J'ai trouvé une approche différente, en utilisant le fournisseur WinNT qui a fait le travail pour moi:

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; 
     } 
    } 

post-scriptum Pour ceux qui ne connaissent pas l'API utilisée ci-dessus: vous devez ajouter une référence à System.DirectoryServices pour l'utiliser.

Le lien que j'ai trouvé m'a aidé avec ceci: How Can I Get User Information Using ADSI Les exemples utilisent ADSI mais peuvent également être appliqués à .NET DirectoryServices. Ils démontrent également d'autres propriétés de l'objet utilisateur qui peuvent être utiles.

+0

amour la nouvelle version, super rapide et exactement ce dont j'avais besoin. Merci! –

Répondre

4

L'espace de noms System.DirectoryServices dans l'article est exactement ce dont vous avez besoin et prévu à cet effet. Si je me souviens bien, il est un wrapper autour des Active Directory Server Interfaces interfaces COM

EDIT:

Quelque chose comme ce qui suit devrait le faire (il pourrait probablement faire avec le contrôle et la manipulation). Il utilisera le domaine du contexte de sécurité actuel pour trouver un contrôleur de domaine, mais cela pourrait facilement être modifié pour passer dans un serveur nommé.

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; 
} 

et testé avec les éléments suivants

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

Ces API sont destinées à l'accès aux informations Active Directory (comme ADO.NET pour les données SQL). Le défi de la programmation AD est de comprendre le schéma et de construire les bonnes requêtes pour obtenir l'information dont vous avez besoin (et il y a une tonne d'informations stockées dans AD). – DSO

+0

@DSO - vous avez le domaine et le nom d'utilisateur, vous devriez donc pouvoir utiliser un objet DirectorySearcher pour trouver si le nom d'utilisateur existe dans ce domaine en instanciant l'objet DirectorySearcher et en passant un objet DirectoryEntry lié au noeud représentant l'objet domaine –

+0

Votre exemple n'a pas fonctionné pour moi, je reçois une erreur "serveur renvoyé une référence", ce qui signifie que le conteneur n'existe pas. Je pense que vous avez raison, en principe, de lier d'abord le conteneur correct, puis de chercher l'objet, donc je vous ai donné un upvote pour ça. Cependant, je ne pense pas que votre approche de construction de la requête à lier au domaine fonctionnera dans tous les environnements. J'ai trouvé une solution plus simple (mise à jour post). – DSO

2

trouvé un moyen simple de le faire si vous êtes sur une version cadre assez élevé:

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; 
    } 
} 
Questions connexes