ASP.NET Identity "Role-based" Claims

29,713

Solution 1

This is already done for you by the framework. When user is logged in, all user roles are added as claims with claims type being ClaimTypes.Role and values are role name.

And when you execute IPrincipal.IsInRole("SuperAdmin") the framework actually checks if the claim with type ClaimTypes.Role and value SuperAdmin is present on the user.

So don't need to do anything special. Just add a user to a role.

Solution 2

You can store roles using the ClaimType Role

claims.Add(new Claim(ClaimTypes.Role, "SuperAdmin"));

Solution 3

You need to specify the Role in a claim with a type of ClaimsType.Role and then specify the claim type that contains the role in the ClaimsIdentity as shown below.

var claimsIdentity = new ClaimsIdentity(new[]
{
    new Claim(ClaimTypes.Email, "[email protected]"),
    new Claim(ClaimTypes.Name, "Peter"),
    new Claim(ClaimTypes.Role, "SuperAdmin"),
},
"ApplicationCookie", ClaimTypes.Email, ClaimTypes.Role);

This will then allow you to use the [Authorize(Roles = "SuperAdmin")] attribute in your controllers.

Share:
29,713

Related videos on Youtube

Dave New
Author by

Dave New

Updated on March 09, 2020

Comments

  • Dave New
    Dave New over 3 years

    I understand that I can use claims to make statements about a user:

    var claims = new List<Claim>();
    claims.Add(new Claim(ClaimTypes.Name, "Peter"));
    claims.Add(new Claim(ClaimTypes.Email, "[email protected]"));
    

    But how should I store "role-based" claims? For example:

    The user is a super administrator.

    claims.Add(new Claim("IsSuperAdmin, "true"));
    

    The value parameter "true" feels completely redundant. How else can this statement be expressed using claims?

  • tymtam
    tymtam over 7 years
    What is the relation between Claims of type Role and AspNetRoles table?
  • trailmax
    trailmax over 7 years
    @Tymski AspNetRoles contains list of roles. When user logs in, all these roles are added into the cookie as claims of type ClaimTypes.Role. Claims in cookie are short-lived. Records in database are just copied into the cookie.
  • Rob
    Rob about 7 years
    I should point out that IPrincipal.IsInRole("xx") does not necessarily use ClaimTypes.Role when searching for a matching claim. For example the WindowsPrincipal you may receive after doing Windows authentication actually uses the ClaimTypes.GroupSid for specifying roles. Instead use the ClaimsIdentity.RoleClaimType property.
  • Rob
    Rob about 7 years
    I made the comment above, but it applies here also: it would be more reliable to use the ClaimsIdentity.RoleClaimType property when adding roles.
  • trailmax
    trailmax about 7 years
    @Rob Context is king. IsInRole is part if IPrincipal interface (referencesource.microsoft.com/#mscorlib/system/security/…) and whatever object implements it can do whatever it does. Here we talk about ClaimsPrincipal (referencesource.microsoft.com/#mscorlib/system/security/cla‌​ims/…) And it uses Claims to define roles. If you happen to get WindowsPrincipal in Identity framework inside your MVC app, you are doing something very wrong.
  • Rob
    Rob about 7 years
    @trailmax WindowsPrincipal derives from ClaimsPrincipal in .Net 4.5, and I believe you'll find that WindowsPrincipal is what you will receive in an ASP.Net Web API (and MVC?) if you configure the application to use windows integrated authentication. But the point here is that using the specific ClaimTypes.Role to drive ClaimsPrincipal.IsInRole is not correct. See ClaimsPrincipal.IsInRole
  • trailmax
    trailmax about 7 years
    @Rob fair enough. I just followed through the source code to this line: referencesource.microsoft.com/#mscorlib/system/security/clai‌​ms/… and hence my reference.
  • trailmax
    trailmax about 7 years
    @Rob though, if you look through ClaimsPrincipal.IsInRole it will lead you to the same constant, pointing to ClaimsTypes.Role. But I'm not sure why there is a need to reference the same constant from different properties. Perhaps backwards compatibility.
  • Rob
    Rob about 7 years
    Hi @trailmax. It's a little esoteric but note that ClaimsPrincipal.IsInRole() uses the property RoleClaimType to test if the contained identity has the required claim. You can see in the reference source for ClaimsIdentity that the backing field for this property defaults to ClaimsType.Role but the WindowsIdentity constructor passes ClaimTypes.GroupSid for this field. I don't the underlying reason, but this is why it is best to use the RoleClaimType property.
  • trailmax
    trailmax about 7 years
    @Rob agreed, one should not be using internal/hidden APIs. But it is good to know what happens under the hood.
  • Alexander Christov
    Alexander Christov almost 7 years
    What about more than one role?
  • Alexander Christov
    Alexander Christov almost 7 years
    Comma separated? Multiple claims with the same type? Other?
  • dpant
    dpant almost 7 years
    @AlexanderChristov Multiple claims with the same type.