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.
Active Directory has two types of groups: Security groups: Use to assign permissions to shared resources. Distribution groups: Use to create email distribution lists.
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.
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.
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;
}
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With