How to create WindowsIdentity/WindowsPrincipal from username in DOMAIN\user format

Knaģis picture Knaģis · Sep 16, 2013 · Viewed 31.1k times · Source

The WindowsIdentity(string) constructor requires the username to be in [email protected] format. But in my case I get the usernames from a DB in the old DOMAIN\user format (and then have to check their Windows role membership).

What is the best way of creating WindowsPrincipal from the old style (sAMAccountName) username?

Answer

Knaģis picture Knaģis · Sep 20, 2013

It does seem that there is no way of converting the username format without involving a query to Active Directory. Since that is the case there is no need to create WindowsPrincipal for checking the group membership since that would probably need yet another connection to AD.

By using the System.DirectoryServices.AccountManagement namespace you can both get the UPN of the user and check the group membership.

string accountName = @"DOMAIN\user";
var groupNames = new[] { "DOMAIN\Domain Users", "DOMAIN\Group2" }; // the groups that we need to verify if the user is member of

// cannot create WindowsIdentity because it requires username in form [email protected] but the passed value will be DOMAIN\user.
using (var pc = new PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain, Environment.UserDomainName))
{
    using (var p = UserPrincipal.FindByIdentity(pc, accountName))
    {
        // if the account does not exist or is not an user account
        if (p == null)
            return new string[0];

        // if you need just the UPN of the user, you can use this
        ////return p.UserPrincipalName;

        // find all groups the user is member of (the check is recursive).
        // Guid != null check is intended to remove all built-in objects that are not really AD gorups.
        // the Sid.Translate method gets the DOMAIN\Group name format.
        var userIsMemberOf = p.GetAuthorizationGroups().Where(o => o.Guid != null).Select(o => o.Sid.Translate(typeof(NTAccount)).ToString());

        // use a HashSet to find the group the user is member of.
        var groups = new HashSet<string>(userIsMemberOf, StringComparer.OrdinalIgnoreCase);
        groups.IntersectWith(groupNames);

        return groups;
    }
}