ASP.NET Core 身份角色、声明和用户

Posted

技术标签:

【中文标题】ASP.NET Core 身份角色、声明和用户【英文标题】:ASP.NET Core Identity Role, Claim and User 【发布时间】:2017-02-03 12:21:42 【问题描述】:

我是 ASP.NET Core 初学者。我陷入了角色、声明和用户关系中。

我有一个用户 Ben,用户属于 Admin 角色。 Admin 角色在数据库中拥有 view-pageedit-page 声明。

但我无法获得属于该用户的声明和角色:

(请看代码中的注释)

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']
    
    

在我看来,我理解当用户是某个角色的成员时,他会继承该角色的声明。

默认 ASP.NET 标识有 5 个表:

用户。 角色。 UserRoles - 一个用户可以拥有多个角色。 RoleClaims - 一个角色可以有许多声明。 UserClaims - 一个用户可以有许多声明。

我认为正确吗?为什么 userManager.GetClaimsAsync(user) 返回空声明?

有什么建议吗?

【问题讨论】:

【参考方案1】:

为什么 userManager.GetClaimsAsync(user) 返回空声明?

因为UserManager.GetClaimsAsync(user) 查询UserClaims 表。相同的 RoleManager.GetClaimsAsync(role) 查询RoleClaims 表。

但是根据 ASP.NET Identity Core 的设计,当用户是角色的成员时,他们会自动继承角色的声明。您可以检查ClaimsPrincipal,例如在控制器操作中:

var claims = User.Claims.ToList();

您可以在UserClaimsPrincipalFactory.cs 中看到从用户创建ClaimsPrincipal 的代码。

【讨论】:

我需要获取用户声明以在 Web api 中创建 JWT,因此如果令牌不包含有效的用户声明/角色,我将无法使用 User.Claims。而且我认为 UserManager.GetClaimsAsync(user) 查询 UserRoles 表是错误的,它究竟是查询 UserClaims 表。您对这种情况有什么建议吗? @trinvh "UserManager.GetClaimsAsync(user) 查询 UserRoles" 是一个错字,谢谢纠正 因为上面的链接,我标记了正确的答案。对于任何想要获得用户声明的人都需要查看 createAsync 方法 帖子中的链接已失效 :-( 试试这个:github.com/aspnet/Identity/blob/master/src/Core/…【参考方案2】:

我最近不得不处理这个问题,要解决通过来自角色的特定声明定位用户的问题,是使用来自角色声明的值创建一个新的声明对象:

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));
                
            
        
    

这使我可以更新/删除带有声明的角色,并将这些更改传递给分配了角色和声明的要重新发布/删除的用户。但是,我仍在寻找更优雅/更简单且代码更少的东西。

【讨论】:

以上是关于ASP.NET Core 身份角色、声明和用户的主要内容,如果未能解决你的问题,请参考以下文章