ARTICLE

Test for Desktop User Group Membership with C#

Posted by Scott Lysle Articles | Security in .NET November 10, 2008
This article describes a simple approach to determining whether or not a logged in user is a member of a group within the context of a desktop application. The approach shown relies upon the use of the user’s current Windows identity.
Reader Level:

Introduction

This article describes a simple approach to determining whether or not a logged in user is a member of a group within the context of a desktop application.  The approach shown relies upon the use of the user's current Windows identity. 

The example shown would be useful for a client-server application in which it was, for example, necessary to restrict access to certain parts of the available functionality based upon the member's role.  For example, you might be working with an application that has administrative and general users; the administrative users might have additional application rights such as the ability to delete records.  If one were to check for group membership in the administrator's group, the application can show or hide such functionality by getting the currently logged in user and checking whether or not that user is a group member.

There are other ways to accomplish the same sort of thing and to accomplish control level locking and the other approaches can be a bit more surgical; however, this is approach is quite easy and may be used to good effect.

GroupCheckDesktop_CS1.gif
 
Figure 1:  Example Desktop Application Showing Group/Identity Information

Getting Started:

In order to get started, unzip the included project and save it to your hard drive.  Open the application and examine the contents in the solution explorer.

GroupCheckDesktop_CS2.gif
 
Figure 2:  Solution Explorer

The solution contains a single application project called "SecurityCheck".  In this case, all of the code necessary to run the demo is contained in a single form class entitled "Form1". 

Code:  Form1.cs

The form class contains a single label control which is used to display the results of a couple of quick tests; during operation, it will look like the screen shot shown in Figure 1. 

The class begins with the default imports (all of the imports are set by default): 

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

Following the imports, the namespace and class declaration are shown:

namespace SecurityCheck

{

 

    /// <summary>

    /// Display security information

    /// for the current user

    /// </summary>

    public partial class Form1 : Form

    {

Following the class declaration, the default constructor appears.

        /// <summary>

        /// default ctor

        /// </summary>

        public Form1()

        {

            InitializeComponent();

        } 

The form load event is used to capture the security related information used to display security related information regarding the current logged in user.  This section is annotated and should be easy enough to follow from the notation.  In general, the class obtains the current user's identity information and examines that user against built-in and specific groups to test for membership.  The class also shows some additional security related information that can be obtained on the user.

        /// <summary>

        /// Collect and display security information

        /// at form load

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void Form1_Load(object sender, EventArgs e)

        {

            // boolean to hold membership test results

            bool bIsGroupie = false;

 

            // get the current identity; from this app, it will

            // be the account the user logged in with

            System.Security.Principal.WindowsIdentity identity =

                System.Security.Principal.WindowsIdentity.GetCurrent();

 

            // get the principal to test the user against a built-in role

            System.Security.Principal.WindowsPrincipal principal =

                new System.Security.Principal.WindowsPrincipal(identity);

 

            // check the user against BUILTIN\Administrator

            if (principal.IsInRole(System.Security.Principal.

WindowsBuiltInRole.Administrator))

            {

                bIsGroupie = true;

            }

 

            // update the display to show whether or not the user

            // is in the admin group

            if (bIsGroupie == true)

                lblIsAdmin.Text = "You are in the Administrator group, you

                    are " + identity.Name.ToString();

            else

                lblIsAdmin.Text = "No, you are not in the administrator

                group, you are " + identity.Name.ToString();

 

            // Show authentication type

            lblIsAdmin.Text += Environment.NewLine +

                "Authentication Type: " + identity.AuthenticationType;

 

            // show whether or not the user is authenticated

            lblIsAdmin.Text += Environment.NewLine +

                "Is Authenticated: " + identity.IsAuthenticated.ToString();

 

            // show whether user is on a guest account

            lblIsAdmin.Text += Environment.NewLine +

                "Is Guest User: " + identity.IsGuest.ToString();

 

            // show the non-translated SID

            lblIsAdmin.Text += Environment.NewLine +

                "Security Identifier (SID): " + identity.Owner.ToString();

 

            // show the translated SID

            lblIsAdmin.Text += Environment.NewLine +

                "Security Identifier: (Plain): " +

                identity.Owner.Translate(typeof(System.Security.

    Principal.NTAccount)).ToString();

           

            // show the windows account token

            lblIsAdmin.Text += Environment.NewLine +

                "Windows Account Token: " + identity.Token.ToString();

 

            // list group memberships

            lblIsAdmin.Text += Environment.NewLine;

            lblIsAdmin.Text += Environment.NewLine + "You are a member of

            these groups";

            lblIsAdmin.Text += Environment.NewLine;

 

            // get a list of group names for the user

            ArrayList groups2 = new ArrayList();

            foreach (System.Security.Principal.IdentityReference group in

            identity.Groups)

            {

                groups2.Add(group.Translate(typeof

                    (System.Security.Principal.NTAccount)).ToString());

            }

 

            // see if the current user is a member of a

            // specific group

            bIsGroupie = false;

            for (int i = 0; i < groups2.Count; i++)

            {

                lblIsAdmin.Text += Environment.NewLine +

                groups2[i].ToString();

 

                string[] splitName = groups2[i].ToString().Split('\\');

 

                try

                {

                    if (splitName[1] == "SomeCustomGroup")

                    {

                        bIsGroupie = true;

                    }

                }

                catch { }

            }

 

            // show specific group membership

            lblIsAdmin.Text += Environment.NewLine;

            lblIsAdmin.Text += Environment.NewLine + "Check for specific

            group membership:";

 

            lblIsAdmin.Text += Environment.NewLine + Environment.NewLine;

 

            if (bIsGroupie == true)

                lblIsAdmin.Text += "You are in the SomeCustomGroup group, you

                are " + identity.Name.ToString();

            else

                lblIsAdmin.Text += "No, you are not in the SomeCustomGroup

                group, you are " + identity.Name.ToString(); 

        }

The only other code contained in the form1 page's code is used to terminate the application; that code is shown here:

        /// <summary>

        /// close this application

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnQuit_Click(object sender, EventArgs e)

        {

            this.Dispose();

        }

That sums up all the code necessary to obtain security information on the user and to make this simple check for group membership.

Summary

The article is pretty short and simple.  The intent was only to show an easy approach to obtaining user information and determining whether or not a user is a member of a group in the context of a Windows desktop application.  The approach may be useful as a means for controlling access to the entire application or parts of the application restricted from general use.

COMMENT USING