Fun with reflection on NonPublic Static methods

by Jason Haley 1. January 2005 01:44

After reading All about statics: Get a charge from statics with seven essential programming tips by K. Scott Allen this week I decided to try something I had been meaning to do for awhile...try to get a list of roles that a current the user belongs to.  The reason behind wanting to do this is the want for more information than the IsInRole(rolename) function gives you.  The IsInRole() function sort of requires you to know what role you really want to check for, but what if you don't know exactly the name of the role?  In a production environment, I really can't come up with an example where this would be used, but it is an interesting educational piece....

So what does getting a listing of roles have to do with reflection and statics?  Well if you do a little reflecting of the methods on the WindowsIdentity class, you will find that there are 2 static methods that sound like they return useful stuff: WindowsIdentity._GetCurrentToken and WindowsIdentity._GetRoles.  Of course both are non public so you can't easily call them directly... so let's call the indirectly (code below).

If you get all the nonpublic static methods of the WindowsIdentity class, you will see that the index for _GetCurrentToken is 5 and the index of _GetRoles is 4 (hence the member level constants _GET_CURRENT_TOKEN and _GET_ROLES).  Once you have the index of the method, then all you need to do is pass in null for the instance object (read Scott Allen's article), and an object array of the parameters (standard invoke stuff) you will get the return value of these non public static methods... which do exacly as they are named (Thanks to Microsoft naming everything so clearly!).  The _GetCurrentToken returns an InPtr of the current Windows user security token (I am making an assumption here) and _GetRoles returns a complete string array listing of all the roles that user belongs to.

On a side note, line 16 isn't needed as I originally thought it would be to get information on a WindowsIdentity.  Seems the methods are direct calls to the execution engine where the actual windows security token is being kept...

    8 class AccessingPrivateStaticMethods

    9     {

   10         private const int _GET_CURRENT_TOKEN = 5;

   11         private const int _GET_ROLES = 4;

   12  

   13         [STAThread]

   14         static void Main(string[] args)

   15         {

   16             AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);

   17             Console.WriteLine("Username: " + System.Threading.Thread.CurrentPrincipal.Identity.Name);

   18             GetRoles();

   19            

   20         }

   21  

   22         /// <summary>

   23         /// Get a list of roles the current user belongs to by using two private static methods on the WindowsIdentity Object

   24         /// WindowsIdentity._GetCurrentToken - gets the current user token

   25         /// WindowsIdentity._GetRoles(InPtr) - gets a rolename listing for a given user token

   26         /// </summary>

   27         static void GetRoles()

   28         {

   29             Type type;

   30             object result;

   31             MethodInfo[] methods;

   32             string [] roles;

   33  

   34             //Get usertoken

   35             //WindowsIdentity._GetCurrentToken

   36             type = typeof(System.Security.Principal.WindowsIdentity);

   37             methods = type.GetMethods(BindingFlags.Static|BindingFlags.NonPublic);

   38             result = methods[_GET_CURRENT_TOKEN].Invoke(null, null);

   39  

   40  

   41             object instance = null;

   42             object[] parameters = new object[] {result};

   43  

   44             //Get user roles

   45             //WindowsIdentity._GetRoles(InPtr usertoken)

   46             result = methods[_GET_ROLES].Invoke(instance, parameters);

   47             roles = (string[])result;

   48  

   49             foreach (string role in roles)

   50             {

   51                 Console.WriteLine(role);

   52             }

   53         }

   54     }

Comments (3) | Post RSSRSS comment feed |

Categories:
Tags:

Comments

Comments are closed