Windows Principal and the MAGIC_NUMBER
A number of our apps use a mixed model of authentication. We have a Windows integrated authorisation site which extracts role information from intranet users, stores it in a cooke, and redirects to a forms aiuth site. Users not on the intranet can access via the forms auth site directly. Part of this process involves enabling impersonation on the windows auth site and extracting role information from the windows princpal. This is done using the code below :-
WindowsIdentity ident = WindowsIdentity.GetCurrent();
WindowsPrincipal princ = new WindowsPrincipal(ident);
princ.IsInRole("DummyRole"); // This call is required so that the subsystem goes and retrieves a list of roles.
FieldInfo field = type.GetField("m_roles", BindingFlags.Instance | BindingFlags.NonPublic);
String[] roles = (String[]) field.GetValue(princ);
return roles;
Notice how we get the string array of role from a private 'm_roles' member. All works fine....mostly... what I didn't know was that this string array is not used if the principal contains more than 23 roles. An internal hashtable i used instead.
The principal object has a 'MAGIC_NUMBER' internal variable that is set at 23. This is the limit after which the internal hashtable is used. So our code wa not working where an intranet user belonged to more than 23 groups.
To fix this, we used some more reflection so change the value of the MAGIC_NUMBER variable. See below :-
Type type = princ.GetType();
// Note: This code sets the 'MAGIC_NUMBER' field of the principal object.
FieldInfo field2 = type.GetField("MAGIC_NUMBER", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
field2.SetValue(princ,30);
The above code sets the MAGIC_NUMBER to 30, so we can now get 30 roles into the string array. This can obviously be changed to as much as you'd like.
So, moral of the story, if you are using reflection to extract roles from a windows principal, be aware oif the MAGIC_NUMBER limit when trying to get the roles from the 'm_roles' string array.
P.S. I assume this MAGIC_NUMBER limit is for performance reasons.