Knaģis Knaģis - 1 month ago 33
C# Question

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

The

WindowsIdentity(string)
constructor requires the username to be in
username@domain.com
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 username?

Answer

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 user@domain.com 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;
    }
}