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 身份角色、声明和用户的主要内容,如果未能解决你的问题,请参考以下文章

ASP .NET CORE 2.2 JWT 和声明网站的身份验证

如何使用 Web Api Asp.Net Core 实现基于声明的授权?

ASP.NET Core Jwt 实现 signinmanager 声明

ASP.NET CORE MVC 身份用户和角色不起作用

关于 ASP.NET Core 中的授权

ASP.NET Core Windows 身份验证和应用程序角色