ASP.NET Identity "Role-based" Claims
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.
Related videos on Youtube
Dave New
Updated on March 09, 2020Comments
-
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 over 7 yearsWhat is the relation between Claims of type Role and AspNetRoles table?
-
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 typeClaimTypes.Role
. Claims in cookie are short-lived. Records in database are just copied into the cookie. -
Rob about 7 yearsI should point out that
IPrincipal.IsInRole("xx")
does not necessarily useClaimTypes.Role
when searching for a matching claim. For example theWindowsPrincipal
you may receive after doing Windows authentication actually uses theClaimTypes.GroupSid
for specifying roles. Instead use theClaimsIdentity.RoleClaimType
property. -
Rob about 7 yearsI made the comment above, but it applies here also: it would be more reliable to use the
ClaimsIdentity.RoleClaimType
property when adding roles. -
trailmax about 7 years@Rob Context is king.
IsInRole
is part ifIPrincipal
interface (referencesource.microsoft.com/#mscorlib/system/security/…) and whatever object implements it can do whatever it does. Here we talk aboutClaimsPrincipal
(referencesource.microsoft.com/#mscorlib/system/security/claims/…) And it uses Claims to define roles. If you happen to getWindowsPrincipal
in Identity framework inside your MVC app, you are doing something very wrong. -
Rob about 7 years@trailmax
WindowsPrincipal
derives fromClaimsPrincipal
in .Net 4.5, and I believe you'll find thatWindowsPrincipal
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 specificClaimTypes.Role
to driveClaimsPrincipal.IsInRole
is not correct. See ClaimsPrincipal.IsInRole -
trailmax about 7 years@Rob fair enough. I just followed through the source code to this line: referencesource.microsoft.com/#mscorlib/system/security/claims/… and hence my reference.
-
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 about 7 yearsHi @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 toClaimsType.Role
but theWindowsIdentity
constructor passesClaimTypes.GroupSid
for this field. I don't the underlying reason, but this is why it is best to use theRoleClaimType
property. -
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 almost 7 yearsWhat about more than one role?
-
Alexander Christov almost 7 yearsComma separated? Multiple claims with the same type? Other?
-
dpant almost 7 years@AlexanderChristov Multiple claims with the same type.