我是 ASP.NET 核心初学者。我陷入了角色、声明和用户关系。
我有一个用户 Ben,用户属于管理员角色。管理员角色在数据库中具有声明查看页和编辑页。
但我无法获得属于该用户的声明和角色:
(请参阅代码中的注释(
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 个表:
- 用户。
- 角色。
- 用户角色 - 一个用户可以有多个角色。
- 角色声明 - 一个角色可以有多个声明。
- 用户声明 - 一个用户可以有多个声明。
我认为正确吗?为什么userManager.GetClaimsAsync(user(返回空声明?
有什么建议吗?
为什么userManager.GetClaimsAsync(user(返回空声明?
因为UserManager.GetClaimsAsync(user)
查询UserClaims
表。与 RoleManager.GetClaimsAsync(role)
查询RoleClaims
表。
但是,当用户是角色的成员时,ASP.NET 标识核心中的设计会自动继承角色的声明。您可以检查ClaimsPrincipal
,例如在控制器操作中:
var claims = User.Claims.ToList();
您可以在 UserClaimsPrincipalFactory 中看到代码.cs该代码从用户创建ClaimsPrincipal
。
我最近不得不处理这个问题,并且要解决通过来自角色的特定声明定位用户的问题,请使用角色声明中的值创建一个新的声明对象:
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));
}
}
}
}
}
这允许我更新/删除具有声明的角色,并将这些更改传递给分配了角色和声明的要重新颁发/删除的用户。但是,我仍在寻找更优雅/更容易使用更少的代码的东西。