ChatGPT解决这个技术问题 Extra ChatGPT

asp.net identity get all roles of logged in user

I created a role based menu for which I followed this tutorial. Some where down that page you'll see this line of code:

String[] roles = Roles.GetRolesForUser();

It returns all roles of the currently logged in user. I was wondering how to accomplish this with the new ASP.NET Identity system?

It's still pretty new and there is not much to find about it.

A great explanation of Claims and Identity for .NET Core : andrewlock.net/introduction-to-authentication-with-asp-net-core (not mine)
The selected answer is not entirely correct. See answer stackoverflow.com/a/63324519/2000301

A
Anthony Chu

Controller.User.Identity is a ClaimsIdentity. You can get a list of roles by inspecting the claims...

var roles = ((ClaimsIdentity)User.Identity).Claims
                .Where(c => c.Type == ClaimTypes.Role)
                .Select(c => c.Value);

--- update ---

Breaking it down a bit more...

using System.Security.Claims;

// ........

var userIdentity = (ClaimsIdentity)User.Identity;
var claims = userIdentity.Claims;
var roleClaimType = userIdentity.RoleClaimType;
var roles = claims.Where(c => c.Type == ClaimTypes.Role).ToList();

// or...
var roles = claims.Where(c => c.Type == roleClaimType).ToList();

According to this doc msdn.microsoft.com/en-us/library/… , there is no Role in ClaimTypes. Do I need to add it or something?
ASP.NET Identity uses System.Security.Claims.ClaimTypes msdn.microsoft.com/en-us/library/…. Also, the ClaimsIdentity object also has a RoleClaimType property that contains the same value and you can use that instead.
Could you update your answer to show me how that will look like in code? Tried a few ways, but I don't see RoleClaimType.
Maybe it's just that things have changed in 2 years, but this doesn't seem to be correct. I just looked in my DB (tables created by EF), and there is a record in the AspNetUserRoles table, but no corresponding record in the AspNetUserClaims table, so Claims don't necessarily get added when a user is added to a Role.
(from c in ((ClaimsIdentity)User.Identity).Claims where c.Type.Equals("role") select c.Value).ToArray() //since asked for array
L
LawMan

Here's an extension method of the above solution.

    public static List<string> Roles(this ClaimsIdentity identity)
    {
        return identity.Claims
                       .Where(c => c.Type == ClaimTypes.Role)
                       .Select(c => c.Value)
                       .ToList();
    }

How to access it ?
This is an extension method off of the "System.Security.Claims.ClaimsIdentity" object.
A
Amal K

After getting the Identity User from SignInManager, call GetRolesAsync on UserManager and pass identity user as parameter.

It will return a list of roles the identity user has enrolled in.

var rolesList = await userManager.GetRolesAsync(identityuser).ConfigureAwait(false);

the selected answer is for claims not the answer for the OP which was asking for roles - this answers the OP
A
Abdul Rahim

Don't use @using System.IdentityModel.Claims namespace, Instead of that use

@using System.Security.Claims

    @using System.Security.Claims
    @using Microsoft.AspNet.Identity
    @{      
       var claimsIdentity = User.Identity as System.Security.Claims.ClaimsIdentity;
       var customUserClaim = claimsIdentity != null ? claimsIdentity.Claims.FirstOrDefault(x => x.Type == "cutomType") : null;
       var customTypeValue= customUserClaim != null ? customUserClaim .Value : User.Identity.GetUserName();
       var roleOfUser = claimsIdentity != null ? claimsIdentity.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role).Value :"User";

}

What is this supposed to answer? Who is using System.IdentityModel.Claims and where?
u
ubi

I don't think any of the answers is entirely correct as they all take the principal identity of the logged in user. User is a ClaimsPrincipal and can have multiple identities (ClaimsPrincipal.Identities property). ClaimsPrincipal.Identity is the principal identity of those identities. So to get all roles of the user you need to get roles from all identities. This is what the built-in ClaimPrincipal.IsInRole(string roleName) method does i.e. it checks the given roleName exists in any of the identities.

So the correct way to get all roles is something like this:

    public static class ClaimsPrincipalExtensions

       public static IEnumerable<string> GetRoles(this ClaimsPrincipal principal)
        {
            return principal.Identities.SelectMany(i =>
            {
                return i.Claims
                    .Where(c => c.Type == i.RoleClaimType)
                    .Select(c => c.Value)
                    .ToList();
            });
        }
    }

and used as

var roles = User.GetRoles()

Also, note the use of claim type set in the identity Identity.RoleClaimType instead of the static claim type ClaimTypes.Role . This is needed because the role claim type can be overridden per identity e.g. when identity is received via a JWT token which provides ability to use a custom claim name as the role claim type.