Requêter Active Directory via .NET

Active Directory, le service d’annuaire de Microsoft se repose sur le protocole LDAP. Pouvoir se connecter à l’Active Directory, y ajouter des utilisateurs, des groupes, etc… est possible avec le framework .NET grâce au namespace System.DirectoryServices.

Avant de commencer le code, il faut ajouter une référence dans votre projet vers System.DirectoryServices.

Se connecter à Active Directory

La connexion se fait en 2 temps. Premièrement, on créé un DirectoryEntry avec le serveur, nom d’utilisateur, mot de passe, etc… Si une correspondance est faite dans l’AD, on continue. Si le couple utilisateur/mot de passe, l’adresse du serveur n’est pas bonne, etc… une exception de type DirectoryServicesCOMException sera levée. Si la connexion est faite, on pourra tester que pour se connecter, l’utilisateur doit être dans le groupe administrateur. Cette recherche se fait à l’aide d’un DirectorySearcher. La syntaxe du filtre est celle propre à LDAP. Le filtre utilisé ci-dessous, vérifie que l’utilisateur a bien pour nom “Aymeric”, qu’il appartient au groupe administrateur et qu’il est bien de type “user”.

string host = "192.168.65.156";
string DN = "DC=aymeric,DC=lan";
string domain = "AYMERIC";
string user = "Aymeric";
string logonName = String.Format(@"{0}\{1}", domain, user);
string password = "Sup1nf0";
string path = String.Format("LDAP://{0}", host);

try
{
    // Connection
    DirectoryEntry de = new DirectoryEntry(path, user, password,
                                           AuthenticationTypes.Secure);

    DirectorySearcher ds = new DirectorySearcher(de);
    ds.Filter = "(&(&(objectClass=user)(memberOf=CN=Administrators,CN=Builtin," +
                DN + "))(samAccountName=" + user + "))";
    SearchResult result = ds.FindOne();
    
    if (result != null)
    {
        Console.WriteLine("Connected....");
    }
    else
    {
        Console.WriteLine("Connection Failed....");
    }
}
catch (DirectoryServicesCOMException ex)
{
    Console.WriteLine(ex.Message);
}

Ajout d’un nouvel utilisateur

La création d’un nouvel utilisateur passe par la création d’un nouveau DirectoryEntry à l’intérieur de celui déjà créé lors de la connexion à l’annuaire. Les informations relatives au nouvel utilisateur sont ensuite ajoutées via la collection de Properties que contient le DirectoryEntry. Le prénom, nom et surnom sont les seules propriétés spécifiées dans l’exemple ci-dessous.

Attention cependant à la propriété “memberOf”, qui contient les groupes auxquels appartient l’utilisateur. Cette propriété est en lecture seule et ne peut donc pas être modifiée. Pour ajouter un utilisateur dans un groupe, il faut partir du groupe en question (décrit plus tard dans l’article).

// Add a user
Console.WriteLine("Add a new user");

string firstName = "Scott";
string lastName = "Guthrie";
string username = "scottgu";
string container = "CN=Users";

string userPath = String.Format("CN={0},{1}", username, container);
DirectoryEntry newUser = de.Children.Add(userPath, "user");
newUser.Properties["samAccountName"].Value = username;
newUser.Properties["givenName"].Value = firstName;
newUser.Properties["sn"].Value = lastName;

newUser.CommitChanges();

string guid = newUser.Guid.ToString();

newUser.Invoke("SetPassword", new object[] { password });
newUser.CommitChanges();

Console.WriteLine("{0} {1} aka {2} is now administrator", firstName, lastName, username);

AD Add user Comme expliqué ci-dessus, ce code est à mettre à la suite de celui établissant la connexion à la base de données. Les exceptions levées par ce code sont toujours du type DirectoryServicesCOMException.

Pour ajouter un groupe, le principe est le même. Dans le Add(), il faut simplement remplacer le 2ème paramètre par “group” et non “user”.

Ajouter un utilisateur à un groupe

Pour ajouter un utilisateur dans un groupe, il faut impérativement que l’utilisateur soit déjà créé, ce qui implique que l’on ne peut pas ajouter un utilisateur à un groupe de la même manière que son nom ou prénom. Il faut, comme expliqué plus haut dans l’article, ajouter un utilisateur via un groupe. Il faut donc recréer un DirectoryEntry qui représente le groupe en question, puis y ajouter l’utilisateur.

// Add scottgu user to Administrators group
Console.WriteLine("Add the new user in the Administrators group");

DirectoryEntry grp = de.Children.Find("CN=Administrators,CN=Builtin");
grp.Invoke("add", newUser.Path);

Console.WriteLine("{0} {1} aka {2} is now administrator", 
                  firstName, 
                  lastName, 
                  username);

Supprimer un utilisateur ou un groupe

Pour supprimer un utilisateur ou un groupe, il faut partir du DirectoryEntry initial (créé pour la connexion) et appeler la méthode Remove() en y passant le DirectoryEntry representant l’objet à supprimer. Dans l’exemple ci-dessous, on supprime l’utilisateur nouvellement créé.

de.Children.Remove(newUser);
de.CommitChanges();

Console.WriteLine("{0} {1} aka {2} is deleted", firstName, lastName, username);

Afin de libérer toute les ressources, il faut fermer les **DirectoryEntry **créés.

newUser.Close();
grp.Close();
de.Close();

Voir également