Barre horizontale de naviagtion

jeudi 11 novembre 2010

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 ».

01string host = "192.168.65.156";
02string DN = "DC=aymeric,DC=lan";
03string domain = "AYMERIC";
04string user = "Aymeric";
05string logonName = String.Format(@"{0}\{1}", domain, user);
06string password = "Sup1nf0";
07string path = String.Format("LDAP://{0}", host);
08
09// Connection
10try
11{
12 DirectoryEntry de = new DirectoryEntry(path, user, password, AuthenticationTypes.Secure);
13
14 DirectorySearcher ds = new DirectorySearcher(de);
15 ds.Filter = "(&(&(objectClass=user) " +
16 "(memberOf=CN=Administrators,CN=Builtin," + DN + "))" +
17 "(samAccountName=" + user + "))";
18 SearchResult result = ds.FindOne();
19
20 if (result != null)
21 {
22 Console.WriteLine("Connected....");
23 }
24 else
25 {
26 Console.WriteLine("Connection Failed....");
27 }
28}
29catch (DirectoryServicesCOMException ex)
30{
31 Console.WriteLine(ex.Message);
32}

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).

01// Add a user
02Console.WriteLine("Add a new user");
03
04string firstName = "Scott";
05string lastName = "Guthrie";
06string username = "scottgu";
07string container = "CN=Users";
08
09string userPath = String.Format("CN={0},{1}", username, container);
10DirectoryEntry newUser = de.Children.Add(userPath, "user");
11newUser.Properties["samAccountName"].Value = username;
12newUser.Properties["givenName"].Value = firstName;
13newUser.Properties["sn"].Value = lastName;
14
15newUser.CommitChanges();
16
17string guid = newUser.Guid.ToString();
18
19newUser.Invoke("SetPassword", new object[] { password });
20newUser.CommitChanges();
21
22Console.WriteLine("{0} {1} aka {2} : {3}", firstName, lastName, username, guid);

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.

1Console.WriteLine("Add the new user in the Administrators group");
2
3DirectoryEntry grp = de.Children.Find("CN=Administrators,CN=Builtin");
4grp.Invoke("add", newUser.Path);
5
6Console.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éé.

1de.Children.Remove(newUser);
2de.CommitChanges();
3
4Console.WriteLine("{0} {1} aka {2} is deleted", firstName, lastName, username);

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

1newUser.Close();
2grp.Close();
3de.Close();

Le projet utilisé pour cet article est disponible ici.

1 commentaire:

  1. Bonjour,

    Petite question, je sais que l'on peut savoir avec System.DirectoryServices si un compte est bloque. Par contre peut on avoir le nombre d'erreur de saisie de mot de passe, l'heure de ces erreurs et eventuellement l'ip source des erreurs?

    Merci,

    DevBio de blog.yvoz.net

    RépondreSupprimer