El otro día estaba jugueteando con la seguridad de una aplicación Windows escrita en .NET, utilizando las clases WindowsPrincipal y WindowsIdentity para probar algunas cosas. El caso es que me parece estupendo que WindowsPrincipal disponga de un método IsInRole que nos permite saber si el usuario que representa se encuentra dentro de un grupo de usuarios o no. Sin embargo me parece un error que no ofrezca propiedad o método alguno para obtener directamente la lista de todos los grupos/roles a los que pertenece el usuario. Creo que sería mucho más cómodo en algunas situaciones, sobre todo cuando no sabemos de antemano qué roles hay disponibles.

Investigando un poco el asunto y utilizando un explorador de clases/decompilador .NET (Anakrino, en concreto) me di cuenta de que la clase WindowsIdentity dispone de un método privado llamado _GetRoles (sí, con guión bajo delante) al que se le debe pasar el token de un usuario y que devuelve una matriz de cadenas de texto. Tiene toda la pinta de servirme par alo que yo quería, así que, digo yo, mediante reflexión será muy sencillo llamarla y ver qué pasa: ¡Voilà!, ¡funcionó!. Esta función es estática (Shared en Visual Basic) en la clase WindowsIdentity y permite obtener una lista con los grupos de usuario a los que pertenece un usuario representado por su Token. Basándome en esto creé una función que, pasándole un objeto WindowsIdentity devuelve una lista de grupos de usuario a los que pertenece. Funciona tanto en autenticación local como contra Active Directory. Este es el código completo con un ejemplo de uso que averigua los roles del usaurio actualmente autenticado en un sistema y los muestra a través de la consola:

using

System;
using System.Collections;
using System.Security.Principal;
using System.Reflection;

public

class Prueba
{
 
public static void Main()
 
{
   
string[] Roles = ListaDeRoles(WindowsIdentity.GetCurrent());
   
foreach (string Role in Roles)
     
Console.WriteLine( Role );
   
Console.ReadLine();
}

// Devuelve la lista de roles de un WindowsIdentity que se le pase
  public static string[] ListaDeRoles(WindowsIdentity wId)
 
{
   
Type tipo = wId.GetType();
   
Object[] arr =
new Object[] {wId.Token};
   
Object oRoles = tipo.InvokeMember("_GetRoles", BindingFlags.Static |
     
BindingFlags.InvokeMethod | BindingFlags.NonPublic,
null, wId, arr);
   
return (string[]) oRoles;
 
}
}

 

Escrito por un humano, no por una IA