Michael JDI
Michael JDI

Reputation: 1251

AspNet5 - Windows Authentication Get Group Name From Claims

I have a asp.net5 project setup to use windows authentication. When I set a break point and look at the User, I see that there is a Claims array that contains Group SID's. How do I get the actual group name from the claims?

I am trying to limit the windows logged in user using the active directory groups that they belong to, and am struggling setting it up.

Questions: How can I see the active directory groups that the logged in user belongs to? How do I convert the GroupSID's to a group name? Do I need to include anything in the startup.cs to limit certain groups to REST service calls?

I see examples of setting up claims manually based upon the logged in user. I am interested in using the Windows authenticated user and their groups to limit access.

Thanks

Upvotes: 19

Views: 12481

Answers (4)

ChronoZZ
ChronoZZ

Reputation: 161

Only adding an answer to help clarify something in the most upvoted answer since I don't have enough rep to add a comment.

That answer does not print out the actual AD Group Name. Replacing role with name in the foreach loop will print out the name of the AD group.

var roles = ((ClaimsIdentity)_context.User.Identity).Claims.Where(q => q.Type == ClaimTypes.GroupSid).Select(q => q.Value);

_logger.LogInformation($"Got {roles.Count()} roles");

foreach (var role in roles)
{
    var name = new System.Security.Principal.SecurityIdentifier(role).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
    _logger.LogInformation($"Got role {name}");
} 

Upvotes: 7

Assaf S.
Assaf S.

Reputation: 4884

Another option (similar to @JosephGarrone's solution):

private string[] GetGroups1()
{
    var groups = new List<string>();

    var wi = (WindowsIdentity)User.Identity;
    if (wi.Groups != null)
    foreach (var group in wi.Groups)
    {
        try
        {                                
            groups.Add(group.Translate(typeof(NTAccount)).ToString());
        } catch (Exception) {
        // ignored
        }
    }

    groups.Sort(); // optional
    return groups.ToArray();
}

Upvotes: 5

JosephGarrone
JosephGarrone

Reputation: 4161

You can actually still get the group name using the following:

var test = new System.Security.Principal.SecurityIdentifier("S-1-5-21-3290390516-4063083420-3538132138-1146").Translate(typeof(System.Security.Principal.NTAccount)).ToString();

So for example:

var roles = ((ClaimsIdentity)_context.User.Identity).Claims.Where(q => q.Type == ClaimTypes.GroupSid).Select(q => q.Value);

_logger.LogInformation($"Got {roles.Count()} roles");

foreach (var role in roles)
{
    var name = new System.Security.Principal.SecurityIdentifier(role).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
    _logger.LogInformation($"Got role {name}");
}

Outputs:

(namespace).Authorization.Handlers.SiteHandler: Information: Got 18 roles
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\Domain Users
(namespace).Authorization.Handlers.SiteHandler: Information: Got role Everyone
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\(redacted) Backend
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\(redacted) Dashboards
(namespace).Authorization.Handlers.SiteHandler: Information: Got role BUILTIN\Performance Log Users
(namespace).Authorization.Handlers.SiteHandler: Information: Got role BUILTIN\Users
(namespace).Authorization.Handlers.SiteHandler: Information: Got role NT AUTHORITY\INTERACTIVE
(namespace).Authorization.Handlers.SiteHandler: Information: Got role CONSOLE LOGON
(namespace).Authorization.Handlers.SiteHandler: Information: Got role NT AUTHORITY\Authenticated Users
(namespace).Authorization.Handlers.SiteHandler: Information: Got role NT AUTHORITY\This Organization
(namespace).Authorization.Handlers.SiteHandler: Information: Got role LOCAL
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\jira-users
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\jira-developers
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\(redacted)_PDMS_DE_ALL
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\(redacted)_PDMS_BE_ALL
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\(redacted)Developers
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\(redacted)_TEST
(namespace).Authorization.Handlers.SiteHandler: Information: Got role (redacted)\(redacted)_PDMS_DB_ALL

Note, it can take a second or two for the domain roles to populate.

Upvotes: 33

blowdart
blowdart

Reputation: 56530

You don't. Unfortunately that's not how Windows authentication works. You can only check if a user is in a role (and there's a Policy requirement for that), not enumerate the roles they are in - that takes directory services and that has not been ported to core.

(One thing to note is that, err, User.IsInRole() is broken right now for Windows identities. That will be fixed in RC2)

Upvotes: 7

Related Questions