C#: Query active directory to get a user’s roles

There are a few different ways to get the roles/groups of user from Active Directory. Here are 3 different ways to do it.

The first way to do it is to use UserPrincipal.FindByIdentity:

private static IEnumerable<string> GetGroupsFindByIdentity(string username, string domainname, string container)
{
	var results = new List<string>();
	using (var context = new PrincipalContext(ContextType.Domain, domainname, container))
	{
		try
		{
			UserPrincipal p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
			if (p != null)
			{
				var groups = p.GetGroups();
				foreach (var group in groups)
				{
					try
					{
						results.Add(@group.Name);
					}
					catch (Exception ex)
					{
					}
				}
			}
		}
		catch (Exception ex)
		{
			throw new ApplicationException("Unable to query Active Directory.", ex);
		}
	}

	return results;
}

You can then print the roles using:

var groups = GetGroupsFindByIdentity("benohead", "aw001.amazingweb.de", "DC=aw001,DC=amazingweb,DC=de");
foreach (var group in groups)
{
	Console.WriteLine(group);
}

Another way to do it is to use a DirectorySearcher and fetching DirectoryEntries:

private static IEnumerable<string> GetGroupsDirectorySearcher(string username, string container)
{
	var searcher =
		new DirectorySearcher(new DirectoryEntry("LDAP://" + container))
		{
			Filter = String.Format("(&(objectClass=user)(samaccountname={0}))", username)
		};
	searcher.PropertiesToLoad.Add("MemberOf");

	var directoryEntriesFound = searcher.FindAll()
		.Cast<SearchResult>()
		.Select(result => result.GetDirectoryEntry());

	foreach (DirectoryEntry entry in directoryEntriesFound)
		foreach (object obj in ((object[]) entry.Properties["MemberOf"].Value))
		{
			string group = Regex.Replace(obj.ToString(), @"^CN=(.*?)(?<!\\),.*", "$1");
			yield return group;
		}
}

The regular expression is required in order to extract the CN part of the returned string.

var groups = GetGroupsDirectorySearcher("benohead", "DC=aw005,DC=amazingweb,DC=de");
foreach (var group in groups)
{
	Console.WriteLine(group);
}

The third way to do it is to use a WindowsIdentity:

private static IEnumerable<string> GetGroupsWindowsIdentity(string userName)
{
	var results = new List<string>();
	var wi = new WindowsIdentity(userName);

	if (wi.Groups != null)
	{
		foreach (var group in wi.Groups)
		{
			try
			{
				results.Add(@group.Translate(typeof (NTAccount)).ToString());
			}
			catch (Exception ex)
			{
				throw new ApplicationException("Unable to query Active Directory.", ex);
			}
		}
	}
	return results;
}

You can then print the roles using:

var groups = GetGroupsWindowsIdentity("benohead");
foreach (var group in groups)
{
	Console.WriteLine(group);
}

You might notice that this last option seems to return more groups than the other two options. I’m not yet sure why. I’ve tested it with multiple users and saw that it does return different groups but for some reason, it also returns groups not returned by any other method. So for now I’ll rather stick to the first or second method.

Leave a Reply

Your email address will not be published. Required fields are marked *