HowTo: Obtener TODOS los usuarios de un grupo del Directorio Activo

Siguiendo con el tema de las últimas entradas, vamos a ver cómo obtener TODOS los usuarios que pertenecen a un grupo del directorio activo. Y cuando digo TODOS los usuarios, me refiero a TODOS (por algo lo he puesto en mayúsculas :-D). Es decir, dentro de un grupo podemos tener otros grupos, que a su vez contengan otros grupos y así succesivamente... y nuestro objetivo es obtener todos los usuarios de forma recursiva.

ADGroups

Para obtener los datos de estos usuarios vamos a crear una clase, para ir almacenando las propiedades que deseamos obtener de cada usuario. Y una función que obtenga los usuarios de un grupo, y se llame a sí misma de forma recursiva en caso que este grupo contenga otros grupos.

El código de la clase:

public class ADUser
{
    public byte[] Sid { get; set; }
    public string Name { get; set; }
    public string DistinguishedName { get; set; }
    public string SAMAccountName { get; set; }
    
    public int RoleType { get; set; }
 
    public ADUser(byte[] sid, string name, 
        string distinguishedName, string sAMAccountName)
    {
        Sid = sid;
        Name = name;
        DistinguishedName = distinguishedName;
        SAMAccountName = sAMAccountName;
    }
 
    public string sIDtoString()
    {
        SecurityIdentifier sid = new SecurityIdentifier(Sid, 0);
        return sid.ToString();
    }
}

Y el método que devuelve todos los usuarios de un grupo de forma recursiva:

namespace Alpha.Code
{
    public class SecurityContextEx
    {
        public static string getDomainName()
        {
            return IPGlobalProperties.GetIPGlobalProperties().DomainName;
        }
 
        public static string getLDAPDomainName(string domainName)
        {
            StringBuilder sb = new StringBuilder();
            string[] dcItems = domainName.Split(".".ToCharArray());
            sb.Append("LDAP://");
            foreach (string item in dcItems)
            {
                sb.AppendFormat("DC={0},", item);
            }
            return sb.ToString().Substring(0, sb.ToString().Length - 1);
        }
 
        public static List<ADUser> GetUsersInGroup(string group)
        {
            List<ADUser> users = new List<ADUser>();
            string ldapDomainName = SecurityContext.getLDAPDomainName(SecurityContext.getDomainName());
            string domainName = ldapDomainName.Replace("LDAP://", string.Empty);
            List<string> groupMemebers = new List<string>();
 
            DirectoryEntry de = new DirectoryEntry(ldapDomainName);
            DirectorySearcher ds = new DirectorySearcher(de, "(objectClass=person)");
 
            ds.Filter = "(&(objectClass=group)(cn=" + group + "))";
            foreach (SearchResult result in ds.FindAll())
            {
                var dir = result.GetDirectoryEntry();
                var list = dir.Invoke("Members");
                IEnumerable entries = (IEnumerable)list;
                foreach (var entry in entries)
                {
                    DirectoryEntry member = new DirectoryEntry(entry);
                    if (member.SchemaClassName == "group")
                    {
                        List<ADUser> usersInGroup =
                            GetUsersInGroup(member.Properties["name"][0].ToString());
                        foreach (ADUser aduser in usersInGroup)
                        {
                            if (!users.ToDictionary(u => u.Name).ContainsKey(aduser.Name))
                            {
                                users.Add(aduser);
                            }
                        }
                    }
                    else
                    {
                        ADUser aduser = new ADUser(
                            (byte[])member.Properties["objectSid"][0],
                            member.Properties["name"][0].ToString(),
                            member.Properties["distinguishedName"][0].ToString(),
                            member.Properties["sAMAccountName"][0].ToString());
                        users.Add(aduser);
                    }
                }
            }
            return users;
        }
    }
}

Aparte de la función GetUsersInGroup, también existen un par de métodos de apoyo para averiguar el nombre de nuestro dominio, que creo recordar que he publicado con anterioridad, pero por si acaso os los he publicado también.

Si deseamos obtener los usuarios de un grupo en particular, basta con usarlo de este modo:

List<ADUser> users = SecurityContextEx.GetUsersInGroup("My users");

Nota: En ocasiones, puede resultar una buena práctica para la administración de la seguridad de nuestras aplicaciones, crear un grupo en el directorio activo con el mismo nombre de la aplicación. Y de este modo conceder acceso a todos los miembros de dicho grupo a nuestra aplicación. En este caso todavía resultaría más sencillo mostrar todos los usuarios a los que hemos concedido acceso:

List<ADUser> users = SecurityContextEx.GetUsersInGroup(Application.ProductName);

Espero que os haya gustado,

Un saludo desde las frías tierras de Andorra :-)

Y después de la nevada de ayer, esta vez más frías que nunca…

Noviembre 2009

Published 30/11/2009 16:58 por Lluis Franco
Comparte este post: