如何获得角色声明?

时间:2017-03-02 16:10:59

标签: asp.net-core asp.net-identity entity-framework-core

我创建了一个用户,并在他身上附加了一个有多项声明的角色。问题是我没有看到使用Entity Framework Core和Identity集成访问它们的直接方法。这就是我理想的做法:

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

但是没有Role属性,只有RoleId。所以我不能包含角色声明。当然,我得到一个单独的查询来获取声明甚至使用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;

但看起来效率低下甚至丑陋。应该有一种方法来进行单个查询。

我最后的希望是Controller.User属性(ClaimsIdentity)。我希望以某种方式巧妙地汇总所有角色的声明。但似乎并没有......

3 个答案:

答案 0 :(得分:1)

您可以使用类似SQL的查询表达式,并获取用户的所有角色的所有声明:

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;

答案 1 :(得分:1)

您可以添加导航属性。

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

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

然后,您必须配置身份数据库上下文:

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

用法:

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

最后,它生成以下查询:

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`

来源:Identity model customization in ASP.NET Core

答案 2 :(得分:-1)

  1. 确保正确添加角色和声明。以下是我如何创建用户并添加声明和角色的示例。

    private async Task<IdentityResult> CreateNewUser(ApplicationUser user, string password = null){
    
        //_roleManger is of type RoleManager<IdentityRole>
        // _userManger is of type UserManager<ApplicationUser>
        //and both are injected in to the controller. 
    
        if (!await _roleManger.RoleExistsAsync("SomeRole")){
            await _roleManger.CreateAsync(new IdentityRole("SomeRole"));
        }
    
        var result = password != null ? await _userManager.CreateAsync(user, password) : await _userManager.CreateAsync(user);
    
        if(result.Succeeded) {
    
            await _userManager.AddToRoleAsync(user, "SomeRole");
            await _userManager.AddClaimAsync(user, new Claim(ClaimTypes.Name, user.Email));
    
        }
    
        return result;
    }
    
  2. 然后,您可以使用_userManager获取声明。 This is how我使用_userManager获取当前用户。然后你可以这样打电话:

    var claims = await _userManager.GetClaimsAsync(user);