Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Role Claims?

I've created a user and attached to him a role that has a number of claims. The problem is I don't see a direct way to access retrieve them using Entity Framework Core and Identity integration. Here's what I'd like to do ideally:

return _context.Users
  .Include(u => u.Roles)
  .ThenInclude(r => r.Role)
  .ThenInclude(r => r.Claims)

But there's not Role property, just RoleId. So I can not Include role claims. Of course I get make a separate query to get claims or even use RoleManager:

var user = _context.Users.Single(x => x.Id == ...);
var role = _roleManager.Roles.Single(x => x.Id ==  user.Roles.ElementAt(0).RoleId);
var claims = _roleManager.GetClaimsAsync(role).Result;

but it looks inefficient and even ugly. There should be a way to make a single query.

My last hope was Controller.User property (ClaimsIdentity). I hoped it somehow smartly aggregates claims from all the roles. But seems like it doesn't...

like image 273
SiberianGuy Avatar asked Mar 02 '17 16:03

SiberianGuy


2 Answers

You can use SQL-like query expressions and get all claims from all roles of a user like this:

var claims = from ur in _context.UserRoles
             where ur.UserId == "user_id"
             join r in _context.Roles on ur.RoleId equals r.Id
             join rc in _context.RoleClaims on r.Id equals rc.RoleId
             select rc;
like image 130
tmg Avatar answered Oct 03 '22 21:10

tmg


You can add navigation properties.

 public class Role : IdentityRole
 {
    public virtual ICollection<RoleClaim> RoleClaims { get; set; }       
 }

  public class RoleClaim : IdentityRoleClaim<string>
  {
     public virtual Role Role { get; set; }
  }

Then you have to configure your identity db context:

 public class MyIdentityDbContext : IdentityDbContext<User, Role, string, IdentityUserClaim<string>, IdentityUserRole<string>, IdentityUserLogin<string>, RoleClaim, IdentityUserToken<string>>

Usage:

await _context.Roles.Include(r => r.RoleClaims).ToListAsync();

At the end it generates the following query:

SELECT `r`.`Id`, `r`.`ConcurrencyStamp`, `r`.`Name`, `r`.`NormalizedName`, `r0`.`Id`, `r0`.`ClaimType`, `r0`.`ClaimValue`, `r0`.`RoleId`
  FROM `roles` AS `r`
  LEFT JOIN `role_claims` AS `r0` ON `r`.`Id` = `r0`.`RoleId`
  ORDER BY `r`.`Id`, `r0`.`Id`

Source: Identity model customization in ASP.NET Core

like image 22
chunk1ty Avatar answered Oct 03 '22 21:10

chunk1ty