ASP.NET Identity "Role-based" Claims
B

3

25

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?

Biopsy answered 9/2, 2015 at 13:18 Comment(0)
C
39

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.

Clough answered 9/2, 2015 at 20:6 Comment(9)
What is the relation between Claims of type Role and AspNetRoles table?Sosthena
@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.Clough
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.Psych
@Psych 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/claims/…) 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.Clough
@Clough 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.IsInRolePsych
@Psych fair enough. I just followed through the source code to this line: referencesource.microsoft.com/#mscorlib/system/security/claims/… and hence my reference.Clough
@Psych 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.Clough
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.Psych
@Psych agreed, one should not be using internal/hidden APIs. But it is good to know what happens under the hood.Clough
L
21

You can store roles using the ClaimType Role

claims.Add(new Claim(ClaimTypes.Role, "SuperAdmin"));
Lemmie answered 9/2, 2015 at 13:25 Comment(4)
I made the comment above, but it applies here also: it would be more reliable to use the ClaimsIdentity.RoleClaimType property when adding roles.Psych
What about more than one role?Unappealable
Comma separated? Multiple claims with the same type? Other?Unappealable
@AlexanderChristov Multiple claims with the same type.Catechism
C
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.

Centreboard answered 20/10, 2017 at 3:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.