Dear fellow dotnetters,

<summary>
If you belong to many NT groups and use WindowsPrincipal, you take a steep
performance hit at first call to IsInRole. I thought I let you all know :-).
</summary>

Avail ago there was a discussion about slow startup times of .Net
applications.
http://discuss.develop.com/archives/wa.exe?A2=ind0203A&L=DOTNET&P=R44017&D=0
&m=47003
The response was not exactly splendid, to say the least. I had some not well
founded theories about it. Well, I've got a little more facts this time.

If you use WindowsPrincipal and do an IsInRole every group membership of
your account is resolved. If you, as I am, are a member in *a lot* of groups
this will take time. Feel free to test the attached program. Credits to Mike
Woodring (look at http://staff.develop.com/woodring/dotnet/#remprincipal).
I've "stolen" the m_roles stuff from him. In the process I discovered that
there must be some threshold making WindowsPrincipal store the roles in a
Hashtable instead of a simple array. (Why not use HybridDictionary? Ah,
maybe to avoid dependencies of another assembly?) Hence the m_rolesTable of
mine.

Regards,
Ingo.Net

--- console app ---
using System;
using System.Security.Principal;
using System.Threading;
using System.Reflection;
using System.Collections;

namespace ConsoleApplication4
{
  class Class1
  {
    [STAThread]
    static void Main(string[] args)
    {
      WindowsIdentity id = WindowsIdentity.GetCurrent();
      WindowsPrincipal wp = new WindowsPrincipal(id);
      wp.IsInRole(""); // make WindowsPrincipal cache all roles I belong to
      ExamineRoles(wp);
    }

    static void ExamineRoles(WindowsPrincipal p)
    {
      try
      {
        // Retrieve roles.
        FieldInfo fi = typeof(WindowsPrincipal).GetField("m_roles",
BindingFlags.Instance | BindingFlags.NonPublic);

        if( fi != null )
        {
          string[] roles = fi.GetValue(p) as string[];
          if( roles != null )
            for( int n = 0; n < roles.Length; n++ )
              if( (roles[n] != null) && (roles[n] != string.Empty) )
                Console.WriteLine(roles[n]);
        }
      }
      catch
      {
      }

      try
      {
        // Retrieve roles, alternative way.
        FieldInfo fi = typeof(WindowsPrincipal).GetField("m_rolesTable",
BindingFlags.Instance | BindingFlags.NonPublic);
        Hashtable tbl = fi.GetValue(p) as Hashtable;
        if (tbl != null)
          foreach(object e in tbl.Values)
            Console.WriteLine(e.ToString());
      }
      catch
      {
      }
    }

  }
}

You can read messages from the DOTNET archive, unsubscribe from DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to