Queremos hacer una aplicación para windows (o para la Web) en .NET donde debemos comprobar si un usuario pertenece o no a unos grupos determinados del dominio. Esto nos sirve para saber si el usuario puede entrar en la aplicación y qué permisos tiene. Lo normal es que un grupo contenga a un usuario directamente, pero, ¿que sucede si un usuario no pertenece directamente a un grupo A, sino que pertenece a un grupo B que a su vez pertenece al grupo A?.
Para que funcione en todos los casos se debe buscar el aributo tokenGroups de la cuenta del usuario en el Directorio Activo. Este atributo contiene todos los SIDs de los grupos a los que pertenece el usuario directa o indirectamente.
Aquí pongo un ejemplo comentando de cómo se puede hacer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
// Creamos un objeto DirectoryEntry para conectarnos al directorio activo DirectoryEntry adsRoot = new DirectoryEntry("LDAP://" + Environment.GetEnvironmentVariable("USERDOMAIN")); // Creamos un objeto DirectorySearcher para hacer una búsqueda en el directorio activo DirectorySearcher adsSearch = new DirectorySearcher(adsRoot); try { // Ponemos como filtro que busque el usuario actual adsSearch.Filter = "samAccountName=" + Environment.GetEnvironmentVariable("USERNAME"); // Extraemos la primera coincidencia SearchResult oResult; oResult = adsSearch.FindOne(); // Obtenemos el objeto de ese usuario DirectoryEntry usuario = oResult.GetDirectoryEntry(); // Obtenemos la lista de SID de los grupos a los que pertenece usuario.RefreshCache(new string[] { "tokenGroups" }); // Creamos una variable StringBuilder donde ir añadiendo los SID para crear un filtro de búsqueda StringBuilder sids = new StringBuilder(); sids.Append("(|"); foreach (byte[] sid in usuario.Properties["tokenGroups"]) { sids.Append("(objectSid="); for (int indice = 0; indice < sid.Length; indice++) { sids.AppendFormat("\\{0}", sid[indice].ToString("X2")); } sids.AppendFormat(")"); } sids.Append(")"); // Creamos un objeto DirectorySearcher con el filtro antes generado y buscamos todas la coincidencias DirectorySearcher ds = new DirectorySearcher(adsRoot, sids.ToString()); SearchResultCollection src = ds.FindAll(); // Recorremos toda la lista de grupos devueltos foreach (SearchResult sr in src) { String sGrupo = (String) sr.Properties["samAccountName"][0]; // A partir de aquí hacer lo que corresponda con cada grupo ... } } catch(Exception ex) { Console.WriteLine(ex.Message); } |
Hola buenas, buen material, pero tengo una dura
que se coloca en:
(«LDAP://» + Environment.GetEnvironmentVariable(«USERDOMAIN»));
por ejemplo tengo usuarios que estan en el domino «Work», eso debo colocar? o la ip de mi servidor?
«samAccountName=» + Environment.GetEnvironmentVariable(«USERNAME»);
aqui va el nombre de un usurio?
por que antes obtengo la cuenta y el nombre
mfigueroa (cuenta) y luego obtengo el nombre «Manuel Figueroa»
gracias
Normalmente poniendo el nombre del dominio ya vale, aunque puedes poner el nombre de la máquina que controla el dominio o la ip de esta.
El usuario deber ser el del dominio (el que introduce para entrar en su sesión).
Hola;
He copiado el codigo que pones para obtener los grupos pero tengo una pregunta. ¿Cuando llamo a esta función que obtengo todos los grupos que hay?
Porque estoy depurando y me aparecen meta el usuario que meta siempre 18 grupos y hay usuarios que no están en todos los grupos.
¿Como puedo hacer que solo me diga los grupos en los que esta el usuario?
Gracias
¿Puede ser que no hayas modificado esta línea: adsSearch.Filter = «samAccountName=» + Environment.GetEnvironmentVariable(«USERNAME»);? Tendría que ser adsSearch.Filter = «samAccountName=» + usuario;
Hola;
Y si necesito mostrar los usuarios de un grupo especifico. ¿Como tendría que hacerlo?
Gracias
Esto te podrá valer http://www.codeproject.com/Articles/18102/Howto-Almost-Everything-In-Active-Directory-via-C#39
Tengo este código y funciona bien en mi local pero al publicarlo en mi servidor IIS siempre me retorna null alguna idea?
¿Qué parte del código te devuelve null?
La parte del sids:
StringBuilder sids = new StringBuilder();
sids.Append(«(|»);
foreach (byte[] sid in usuario.Properties[«tokenGroups»])
{
sids.Append(«(objectSid=»);
for (int indice = 0; indice < sid.Length; indice++)
{
sids.AppendFormat("\\{0}", sid[indice].ToString("X2"));
}
sids.AppendFormat(")");
}
sids.Append(")");