Welcome to MSDN Blogs Sign in | Join | Help

Which Groups Does WindowsIdentity.Groups Return?

WindowsIdentity exposes a Groups property which returns a collection of IdentityReferences for the groups that a particular user is a member of.  However, if you look closely, you'll find that these returned groups won't necessarily include all of the groups that the user is a member of.

Under the covers, WindowsIdentity populates the groups collection by querying Windows for information on the groups that the user token is a member of.  However, before returning this list, the Groups property filters out some of the returned groups.

Specifically, any groups which were on the token for deny-only will not be returned in the Groups collection.  Similarly, a group which is the SE_GROUP_LOGON_ID will not be returned.

Generally, this is exactly the behavior you want.  For instance, if your application is going allow a specific action because the user is a member of a group, you don't want to allow it if the user is a member of the group for deny-only.

If you want to retrieve all of the groups however, there's not an easy built-in way for you to do this.  Instead, you'll have to P/Invoke to the GetTokenInformation API to retrieve the groups yourself.

It can be interesting to dump out the groups that specific users are part of -- here's a simple little snippet of code that does just that.  (And uses some of those fancy new C# 3.0 features to display them grouped by domain):

    public static void Main()

    {

        using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent())

        {               

            var groups = // Get all of the groups from our account, and translate them from IdentityReferences to NTAccounts  

                        from groupIdentity in currentIdentity.Groups

                        where groupIdentity.IsValidTargetType(typeof(NTAccount))

                        select groupIdentity.Translate(typeof(NTAccount)) as NTAccount into ntAccounts

 

                        // Sort the NTAccounts by their account name

                        let domainName = ntAccounts.GetDomainName()

                        let groupName = ntAccounts.GetAccountName()

                        orderby domainName

 

                        // Group the sorted accounts by the domain they belong to, and sort the grouped groups by domain name

                        group ntAccounts by domainName into domainGroups

                        orderby domainGroups.Key

                        select domainGroups;

 

            foreach (var domainGroups in groups)

            {

                Console.WriteLine("Groups from domain: {0}", domainGroups.Key);

 

                foreach (var group in domainGroups)

                {

                    Console.WriteLine("    {0}", group.GetAccountName());

                }

            }

        }

    }

 

    private static string GetDomainName(this NTAccount account)

    {

        string[] split = account.Value.Split('\\');

        return split.Length == 1 ? String.Empty : split[0];

    }

 

    private static string GetAccountName(this NTAccount account)

    {

        string[] split = account.Value.Split('\\');

        return split[split.Length - 1];

    }

Published Thursday, February 07, 2008 9:00 AM by shawnfa
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker