ASP.NET Core Identity Role, Claim and User
Why userManager.GetClaimsAsync(user) returns empty claims ?
Because UserManager.GetClaimsAsync(user)
queries the UserClaims
table. Same for
RoleManager.GetClaimsAsync(role)
queries the RoleClaims
table.
But by design in ASP.NET Identity Core when a user is a member of a role, they automatically inherit the role's claims. You can check the ClaimsPrincipal
, for example inside a controller action:
var claims = User.Claims.ToList();
You can see the code in UserClaimsPrincipalFactory.cs that creates a ClaimsPrincipal
from an user.
I have had to deal with this issue recently and to solve the problem of locating Users by a particular Claim that came from a Role is to create a new Claim object with the values from the Role Claim:
var role = await roleManager.FindByNameAsync(yourRoleName);
if(role != null)
{
var roleClaims = await roleManager.GetClaimsAsync(role);
if(roleClaims != null && roleClaims.Count() > 0)
{
foreach(var claim in roleClaims.ToList())
{
var users = await userManager.GetUsersForClaimAsync(new Claim(claim.Type, claim.Value));
if(users != null && users.Count() > 0)
{
foreach(var user in users.ToList())
{
//This is an example of only removing a claim, but this is the
//area where you could remove/add the updated claim
await userManager.RemoveClaimAsync(user, new Claim(claim.Type, claim.Value));
}
}
}
}
}
This allowed me to Update/Delete a role with claims and pass those changes to the Users to be Re-Issued/Removed that were assigned the roles and claims. However, I am still looking for something more elegant/easier with less code.