Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WindowsPrincipal.IsInRole not working

1,001 views
Skip to first unread message

K. Shier

unread,
Sep 24, 2003, 5:15:09 PM9/24/03
to
VB.Net 2002, developing under Win2k pro, server is running Win2k server

i am trying to put some role-based security into my application. the roles
are based on permission Groups which i've already created on the domain
controller. according to what i've read on the subject, a WindowsPrincipal
should provide a direct mechanism to determine if the user is a member of
one of these Groups or not, but i can't get it to work.


here's a simplified excerpt from my prog:

Public Sub SomeSecuredFeature()
Dim MyIdentity As System.Security.Principal.WindowsIdentity =
System.Security.Principal.WindowsIdentity.GetCurrent
Dim MyPrincipal As New
System.Security.Principal.WindowsPrincipal(MyIdentity)

If MyPrincipal.IsInRole("DRS\DRS Administrators") Then
'allow the user do something
Else
'disallow
End If
End Sub

problem is, i can never get a True result for .IsInRole.

the Group name is 'DRS Administrators' and according to AD Users And
Computers, i am a member of it!. the domain name is 'DRS', & the DC's
machine name is 'DRSSERVER'

i have tried a ludicrous number of permutations of what i *THINK* the name
of the group might be: e.g. "DRS Administrators" (no machine/domain
qualifier) "DRSSERVER\DRS Administrators" (machine name instead of domain
name), "\\DRS\DRS Administrators" (leading backslashes?!), and even
"drsserver.local/Users/DRS Administrators" (full AD object name). i have
even tried matching the System groups like Administrators (which i am also a
member of) and never get a match!

seriously - i've tried every combination of these various formats for
writing the group/role string, but no success...


what am i missing here?

is there NOT a direct correlation between a DC's Groups and a .Net
WindowsPrincipal's 'Roles'? if not, how do i define the relationship
between them?

also, is there some method in .Net to simply query the DC and get a list of
all the Groups?


any insight would be much appreciated! THANKS! =)


Joe Kaplan (MVP - ADSI)

unread,
Sep 24, 2003, 10:37:22 PM9/24/03
to
A couple of things:

WindowsPrincipal definitely matches group names with "domain\group name"
where domain is either the domain or local machine name and group name is
the samAccountName of the group. A bug in Framework 1.0 exists where role
name checks are case sensitive for WindowsPrincipal.IsInRole. This is fixed
in 1.1, but it may be screwing you up.

When I've been in a jam with these things, I've used reflection to call the
private _GetRoles method of WindowsIdentity so that I can see the actual
array of role names. You shouldn't use this in production, but it is really
helpful for debugging.

(VB.NET code snippet)

Dim id As WindowsIdentity = WindowsIdentity.GetCurrent()

Dim idType As Type
idType = GetType(WindowsIdentity)
Dim result As Object = idType.InvokeMember("_GetRoles",
BindingFlags.Static Or BindingFlags.InvokeMethod Or BindingFlags.NonPublic,
Nothing, id, New Object() {id.Token}, Nothing)
Dim roles() As String = DirectCast(result, String())

HTH,

Joe K.

"K. Shier" <ks4...@spamAtYourOwnRisk.yahoo.com> wrote in message
news:uRTm7Aug...@TK2MSFTNGP09.phx.gbl...

K. Shier

unread,
Sep 25, 2003, 11:37:50 AM9/25/03
to
thanks Joe! i just checked that out and it looks like it is going to work.

i appreciate the code snippet as i wouldn't even have known where to begin!
(until a couple minutes ago, my definition of 'reflection' was sitting at my
desk resting my chin on my hands thinking "I sure am screwed..."!)

for some reason the network admin told me to create the security groups as
'Domain Local' instead of 'Global'. but only groups that are Global show up
in WindowsIdentity's _GetRoles method. i don't understand why, but that's
only because i have no idea what the distinction is between a 'Global' and
'Domain Local' group! (i have very limited experience administrating Win2k
nets.)

FYI: i _am_ on framework 1.0, and it did occur to me briefly that
case-sensitivity might be the issue, but since the capitalization is correct
in my strings, i didn't give it any further thought. if i had known earlier
about the bug, i probably would have dwelled on capitaliztion forever,
thinking _that_ was the problem! =)

now i just need to know if there is any way to reset the scope of the
security groups i've created to 'Global' or will i have to delete then
re-create them all? but i think that's a topic for another NG...

THANKS AGAIN! =)

--------------

"Joe Kaplan (MVP - ADSI)" <joseph....@removethis.accenture.com> wrote
in message news:uRRZz3w...@tk2msftngp13.phx.gbl...

K. Shier

unread,
Sep 25, 2003, 11:58:17 AM9/25/03
to
If MyPrincipal.IsInRole("\\DRS\Administrators") Then
MsgBox("\\DRS\admins")
ElseIf MyPrincipal.IsInRole("\\DRS\Administrator") Then
MsgBox("\\DRS\admin")
ElseIf MyPrincipal.IsInRole("DRS\Administrators") Then
MsgBox("DRS\admins")
ElseIf MyPrincipal.IsInRole("DRS\Administrator") Then
MsgBox("DRS\admin")
ElseIf MyPrincipal.IsInRole("\\Administrators") Then
MsgBox("\\admins")
ElseIf MyPrincipal.IsInRole("\\Administrator") Then
MsgBox("\\admin")
ElseIf MyPrincipal.IsInRole("Administrators") Then
MsgBox("admins")
ElseIf MyPrincipal.IsInRole("Administrator") Then
MsgBox("admin")
ElseIf MyPrincipal.IsInRole("\\DRSSERVER\Administrators") Then
MsgBox("\\DRSSERVER\admins")
ElseIf MyPrincipal.IsInRole("\\DRSSERVER\Administrator") Then
MsgBox("\\DRSSERVER\admin")
ElseIf MyPrincipal.IsInRole("DRSSERVER\Administrators") Then
MsgBox("DRSSERVER\admins")
ElseIf MyPrincipal.IsInRole("DRSSERVER\Administrator") Then
MsgBox("DRSSERVER\admin")
ElseIf
MyPrincipal.IsInRole("\\drsserver.local/Users/Administrators") Then
MsgBox("\\drsserver.local/Users/admins")
ElseIf MyPrincipal.IsInRole("\\drsserver.local/Users/Administrator")
Then
MsgBox("\\drsserver.local/Users/admin")
ElseIf MyPrincipal.IsInRole("drsserver.local/Users/Administrators")
Then
MsgBox("drsserver.local/Users/admins")
ElseIf MyPrincipal.IsInRole("drsserver.local/Users/Administrator")
Then
MsgBox("drsserver.local/Users/admin")
ElseIf MyPrincipal.IsInRole("\\DRS\DRS Administrators") Then
MsgBox("\\DRS\DRS Admins")
ElseIf MyPrincipal.IsInRole("\\DRS\DRS Administrator") Then
MsgBox("\\DRS\DRS Admin")
ElseIf MyPrincipal.IsInRole("DRS\DRS Administrators") Then
MsgBox("DRS\DRS Admins")
ElseIf MyPrincipal.IsInRole("DRS\DRS Administrator") Then
MsgBox("DRS\DRS Admin")
ElseIf MyPrincipal.IsInRole("\\DRS Administrators") Then
MsgBox("\\DRS Admins")
ElseIf MyPrincipal.IsInRole("\\DRS Administrator") Then
MsgBox("\\DRS Admin")
ElseIf MyPrincipal.IsInRole("DRS Administrators") Then
MsgBox("DRS Admins")
ElseIf MyPrincipal.IsInRole("DRS Administrator") Then
MsgBox("DRS Admin")
ElseIf MyPrincipal.IsInRole("\\DRSSERVER\DRS Administrators") Then
MsgBox("\\DRSSERVER\DRS Admins")
ElseIf MyPrincipal.IsInRole("\\DRSSERVER\DRS Administrator") Then
MsgBox("\\DRSSERVER\DRS Admin")
ElseIf MyPrincipal.IsInRole("DRSSERVER\DRS Administrators") Then
MsgBox("DRSSERVER\DRS Admins")
ElseIf MyPrincipal.IsInRole("DRSSERVER\DRS Administrator") Then
MsgBox("DRSSERVER\DRS Admin")
ElseIf MyPrincipal.IsInRole("\\drsserver.local/Users/DRS
Administrators") Then
MsgBox("\\drsserver.local/Users/DRS Admins")
ElseIf MyPrincipal.IsInRole("\\drsserver.local/Users/DRS
Administrator") Then
MsgBox("\\drsserver.local/Users/DRS Admin")
ElseIf MyPrincipal.IsInRole("drsserver.local/Users/DRS
Administrators") Then
MsgBox("drsserver.local/Users/DRS Admins")
ElseIf MyPrincipal.IsInRole("drsserver.local/Users/DRS
Administrator") Then
MsgBox("drsserver.local/Users/DRS Admin")
Else
MsgBox("no match")
End If

"K. Shier" <ks4...@spamAtYourOwnRisk.yahoo.com> wrote in message
news:uRTm7Aug...@TK2MSFTNGP09.phx.gbl...

Joe Kaplan (MVP - ADSI)

unread,
Sep 25, 2003, 12:37:24 PM9/25/03
to
That is an Active Directory question, but you should be able to change the
type of the group unless it contains members that they current group cannot
contain or if it is nested in another group that cannot contain a group of
the new type. The Active Directory reference in MSDN explains all of this.

I actually don't understand why domain local groups don't get pulled into
your token, but there are lots of things about AD that I still find
confusing too.

Reflection is cool, isn't it? :)

Good luck,

Joe K.
"K. Shier" <ks4...@spamAtYourOwnRisk.yahoo.com> wrote in message

news:%23VsuHp3...@TK2MSFTNGP11.phx.gbl...

K. Shier

unread,
Sep 29, 2003, 11:43:11 AM9/29/03
to
"Joe Kaplan (MVP - ADSI)" <joseph....@removethis.accenture.com> wrote
in message news:#tzVPN4g...@TK2MSFTNGP11.phx.gbl...

> That is an Active Directory question, but you should be able to change the
> type of the group unless it contains members that they current group
cannot
> contain or if it is nested in another group that cannot contain a group of
> the new type. The Active Directory reference in MSDN explains all of
this.

well, although it pained me to do so, i just deleted and re-created them,
since timely answers on how to edit them were not forthcoming. there were
only a few anyway...

> Reflection is cool, isn't it? :)

yes - and one of those things we are using all the time without thinking
about it. now that i know what it is, i'll think about it more, which might
be a good way to start down the path of 'knowing when you should use it'!
(i'd like to know how you arrived at the values of all the args you pass to
.InvokeMember in that example... for now it's just one of those things i
look at and accept at face value knowing that it comes from a 'higher
source' =)

thanks again for the info!! =)

Joe Kaplan (MVP - ADSI)

unread,
Sep 30, 2003, 12:00:25 AM9/30/03
to
Do a Google search for Reflector and/or Anakrino. They are excellent type
browser/reverse compilers and are very helpful for figuring out how things
work. That's how I figured out there was a private method called _GetRoles
that returns an array which is used by the IsInRole method. ILDASM is also
very helpful, but it doesn't give you nice VB.NET or C#. Reflector is my
new favorite. Also, Rotor, the Shared Source implementation of the .NET
Framework is very helpful as even has commented source code for much of the
base class library.

Regarding the rules on what to call and such, it is pretty simple. You
shouldn't call things that violate encapsulation rules except perhaps for
experimentation. In my earlier example, I called a private method which I
could not call without reflection. So basically, private and internal
(friend) should be off limits for production code as there is no guarantee
that the implementation won't change later or that you are calling the
member safely.

Joe K.

"K. Shier" <ks4...@spamAtYourOwnRisk.yahoo.com> wrote in message

news:uqd5u%23phDH...@TK2MSFTNGP11.phx.gbl...

0 new messages