Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core Identity Role, Claim and User

I am an ASP.NET Core beginner. I'm stuck in role, claim and user relationship.

I have a user Ben, user belongs to Admin role. Admin role has claims view-page and edit-page in database.

But I can't get claims and roles to be belonging to that user:

(Please see comment in code)

var user = await _userManager.FindByNameAsync(applicationUser.UserName);
if(user != null) {
    var userClaims = await _userManager.GetClaimsAsync(user); // empty, WHY ?
    var userRoles = await _userManager.GetRolesAsync(user); // ['admin']
    var adminRole = DbContext.Roles.FirstOrDefault(x => x.Name == "Admin");
    IList<Claim> adminClaims;
    if(adminRole != null)
    {
        adminClaims = await _roleManager.GetClaimsAsync(adminRole);
        // correct => ['view-page', 'edit-page']
    }
    }
}

In my mind, I understand when a user is a member of a role, he inherit that role's claims.

Default ASP.NET Identity have 5 tables:

  • Users.
  • Roles.
  • UserRoles - A user can have many roles.
  • RoleClaims - A role can have many claims.
  • UserClaims - A user can have many claims.

Do i think correct ? Why userManager.GetClaimsAsync(user) returns empty claims ?

Any suggestion?

like image 576
trinvh Avatar asked Feb 03 '17 12:02

trinvh


People also ask

What are claims in ASP.NET Core identity?

A claim is a name value pair that represents what the subject is, not what the subject can do. For example, you may have a driver's license, issued by a local driving license authority. Your driver's license has your date of birth on it.

What is the difference between roles and claims?

In Role-based authorization, applications enforce access by roles. These roles can be used in authorized attributes in your code. Alternatively, claims-based authorization enforces permissions by using information about the user rather than relying on a single role declaration.

What occurs when a user claims and identity?

The claims-based identity process is as follows: A user requests access to an application. The application sends a request to the STS for a token for that user. The STS authenticates the user, e.g., with a password, biometric scan or smart card.


2 Answers

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.

like image 112
Wayne Davis Avatar answered Sep 24 '22 08:09

Wayne Davis


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.

like image 28
tmg Avatar answered Sep 22 '22 08:09

tmg