Hey Guys,

I'm creating an application that will require specific privileges. Users will eventually be add/removed from this group; I was wondering if there's a way I can tie in an Active Directory group to the software? Something that would let me say "if you're part of this group you can do this". That way I wouldn't have to modify the source every time a new users is added/removed from the "admin" group.

I have this part working - but I'm not sure how to check against domain groups rather than built in groups:

namespace REG_Asset_Checkout
{
    public partial class main_Form : Form
    {
        public main_Form()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            System.Security.Principal.WindowsIdentity identity;
            identity = System.Security.Principal.WindowsIdentity.GetCurrent();

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

//extra stuff
            DirectoryEntry de = new DirectoryEntry("WinNT://REG/REG-Pentree1", "ctote", "Lynn790*");
            foreach (DirectoryEntry child in de.Children)
            {
                directory_textBox.AppendText(child.SchemaClassName + ": " + child.Name + "\n");
                
            }           

        }
    }
}

It is used to test if the current user is in a particular role (group).
E.g.

if(System.Threading.Thread.CurrentPricipal.IsInRole("Administrators"))
{
    // Do the allowed action
}
else
{
    MessageBox.Show("Your do not have access to this feature.");
}

Ok, how do you check domain groups though?
Here's what I have so far:

// Create the context for the principal object. 
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "REG");

            // Retrieve the group principal object for the group you need.
            GroupPrincipal groupPrincipal =   
                            GroupPrincipal.FindByIdentity(ctx, "Domain Admins");

            // Find the principal object for which you wish to check membership.
            UserPrincipal userPrincipal = 
                              UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "ctote");

            // Check to see if this user is a member of the "Administrators" group.
            bool isMember = userPrincipal.IsMemberOf(groupPrincipal);



            if (isMember)
            {
                directory_textBox.AppendText("Yeap \n");
            }
            else
            {
                directory_textBox.AppendText("Nope \n");
            }

If I could find a way to translate "ctote" to something like

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

that would be great. I tried replacing "ctote" with identity.ToString() but no luck.

Edited 6 Years Ago by Duki: n/a

OK, you are clearly a bit ahead of me. I only have VS2005 (i.e. .Net 2.0) and GroupPrincipal was introduces in .Net 3.5.
However, having looked at MSDN you probably need UserPrincipal.Current .

// Create the context for the principal object. 
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "REG");

            // Retrieve the group principal object for the group you need.
            GroupPrincipal groupPrincipal =   
                            GroupPrincipal.FindByIdentity(ctx, "Domain Admins");

            // Check to see if this user is a member of the "Administrators" group.
            bool isMember = UserPrincipal.Current.IsMemberOf(groupPrincipal); //<-- modified code

            if (isMember)
            {
                directory_textBox.AppendText("Yeap \n");
            }
            else
            {
                directory_textBox.AppendText("Nope \n");
            }

Edited 6 Years Ago by nick.crane: n/a

Comments
Excellent - thanks for the sample code!

It's messing up again for some reason - I added a database to the project and now it doesn't check my domain for the groups. Here's the updated code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;


namespace REG_Asset_Checkout
{
    public partial class main_Form : Form
    {
        public main_Form()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            MessageBox.Show("You are a Domain Admin - Controls Unlocked!", "Authentication Notice", MessageBoxButtons.OK, MessageBoxIcon.Information);

        }

        private void main_Form_Load(object sender, EventArgs e)
        {
            // TODO: This line of code loads data into the 'reg_checkoutDataSet.Laptops' table. You can move, or remove it, as needed.
            this.laptopsTableAdapter.Fill(this.reg_checkoutDataSet.Laptops);

            // Create the context for the principal object. 
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "REG");

            // Retrieve the group principal object for the group you need.
            GroupPrincipal groupPrincipal =
                            GroupPrincipal.FindByIdentity(ctx, "Domain Admins");

            // Check to see if this user is a member of the "Administrators" group.
            bool isMember = UserPrincipal.Current.IsMemberOf(groupPrincipal);

            if (isMember)
            {
                button1.Enabled = true;
                MessageBox.Show("You are a Domain Admin - Controls Unlocked!", "Authentication Notice", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                button1.Enabled = false;
                MessageBox.Show("You are not a Domain Admin - Controls locked!", "Authentication Notice", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
    }
}

It's acting like it doesn't even get to my if() - maybe it's locking up or something. but I can still modify other controls on the form (e.g., the combo box with database connection).

Further investigation shows that if I put MessageBox.Show("Test") before the database query, it works fine; if I put it directly after the database query, it doesn't work.

Edited 6 Years Ago by Duki: n/a

I don't recommend loading the dataset in Form_Load.
Form_Load generally does not like taking a long time and DataAdapters can do that.
If you need to load the dataset before the user sees the form then move the fill instruction to the Form_Shown event.
You'll probably end up doing this somewhere else anyway.

Edited 6 Years Ago by nick.crane: n/a

This question has already been answered. Start a new discussion instead.