Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WindowsPrincipal.IsInRole and universal vs. global active directory groups

Does anybody know how to make WindowsPrincipal.IsInRole("domain\role") work with active directory universal groups?

Let's say the current user is a member of a group called Role in a domain called domain, and that the Role group is a Global group in active directory. The following code would then yield result = true:

WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool result = wp.IsInRole(@"domain\Role");

But if the Role group is changed to a universal group the code yields result = false.

like image 628
sindre j Avatar asked Nov 27 '08 13:11

sindre j


People also ask

What are the two types of groups in Active Directory?

Active Directory has two types of groups: Security groups: Use to assign permissions to shared resources. Distribution groups: Use to create email distribution lists.

What is a global group in Active Directory?

Global groupsA global group can be used to assign permissions for access to resources in any domain. The global scope can contain user accounts and global groups from the same domain, and can be a member of universal and domain local groups in any domain.

What is the best practice for nesting groups?

Best Practices for Nesting Groups in Active DirectoryAdding user and computer accounts to global groups. Adding global groups to domain local groups. Granting the domain local groups access to resources. Assigning permissions to domain local groups for appropriate access.


1 Answers

I found no good answer to my question, what I had to do was to write a new Principal class that scanned the directory for all groups that the user belongs to, and recursivly scan all those groups to solve group-in-group memberships. Code provided for users with the same problem. It's not the prittiest code I've written, but atleast it works.

Use like this:

var wp = new WindowsPrincipalEx(WindowsIdentity.GetCurrent());
result = wp.IsInRole(@"domain\role");



public class WindowsPrincipalEx : IPrincipal
{
    // Dictionary to store all groups, key = uppercase groupname, value = groupname as entered in AD
    private Dictionary<string,string> completeGroupList = new Dictionary<string,string>();
    // Private vars
    private WindowsIdentity identity;
    private string domain;

    // Identity property
    public IIdentity Identity
    { 
        get { return identity; }
    }

    // Constructor, accepts identity
    public WindowsPrincipalEx(IIdentity identity)
    {
        this.identity = (WindowsIdentity)identity;
        // Find domain name and store it for filtering purposes
        if (identity.Name.Contains('\\'))
            this.domain = identity.Name.Substring(0, identity.Name.IndexOf('\\') + 1);

        // Find all groups this user belongs to, and store the list for later use
        getRoles(completeGroupList);
    }

    public bool IsInRole(string role)
    {
        // Remove domain
        if (role.StartsWith(domain, StringComparison.CurrentCultureIgnoreCase))
            role = role.Substring(domain.Length);
        return completeGroupList.ContainsKey(role.ToUpper());
    }

    private void getRoles(Dictionary<string,string> groupList)
    {
        // Find username and remove domain
        string name = Identity.Name.Replace(domain,"");

        // Find user in AD
        DirectorySearcher search = new DirectorySearcher("(&(sAMAccountName="+name+")(objectCategory=user))");
        search.PropertiesToLoad.Add("memberof");

        SearchResult result = search.FindOne();
        if (result != null)
        {
            // Add all groups to the groupList dictionary
            foreach (string s in result.Properties["memberOf"])
            {
                string[] elements = s.Split(new char[] { ',' });
                foreach (string e in elements)
                    if (e.StartsWith("CN=", StringComparison.CurrentCultureIgnoreCase))
                    {
                        if (!groupList.ContainsKey(e.Substring(3).ToUpper()))
                            groupList.Add(e.Substring(3).ToUpper(),e.Substring(3));
                        break;
                    }
            }
        }

        // Scan through all groups found, and find group on group memberships recursevly
        foreach (var ng in groupList.ToArray())
            getRolesInRoles(groupList, ng.Key);
    }

    private void getRolesInRoles(Dictionary<string, string> groupList, string roleName)
    {
        string name = roleName.Replace(domain, "");

        // Find group in AD
        DirectorySearcher search = new DirectorySearcher("(&(cn="+name+")(objectCategory=group))");
        search.PropertiesToLoad.Add("memberof");

        SearchResult result = search.FindOne();
        if (result != null)
        {
            // Add all groups to the groupList dictionary
            foreach (string s in result.Properties["memberOf"])
            {
                string[] elements = s.Split(new char[] { ',' });
                foreach (string e in elements)
                    if (e.StartsWith("CN=", StringComparison.CurrentCultureIgnoreCase))
                    {
                        if (!groupList.ContainsKey(e.Substring(3).ToUpper()))
                        {
                            groupList.Add(e.Substring(3).ToUpper(),e.Substring(3));
                            getRolesInRoles(groupList, e.Substring(3));
                        }
                        break;
                    }
            }
        }
    }
}
like image 166
sindre j Avatar answered Nov 03 '22 21:11

sindre j