ASP.NET 核心身份角色、声明和用户
ASP.NET Core Identity Role, Claim and User
我是 ASP.NET 核心初学者。我陷入角色、声明和用户关系中。
我有一个用户 Ben,用户属于 Admin 角色。 Admin 角色在数据库中拥有 view-page 和 edit-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) returns 空声明?
有什么建议吗?
Why userManager.GetClaimsAsync(user) returns empty claims ?
因为UserManager.GetClaimsAsync(user)
查询了UserClaims
table。同为
RoleManager.GetClaimsAsync(role)
查询 RoleClaims
table.
但根据 ASP.NET Identity Core 中的设计,当用户是某个角色的成员时,他们会自动继承该角色的声明。您可以检查 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));
}
}
}
}
}
这让我可以 Update/Delete 一个具有声明的角色,并将这些更改传递给用户 Re-Issued/Removed ,这些用户被分配了角色和声明。但是,我仍在寻找更多 elegant/easier 代码更少的东西。
我是 ASP.NET 核心初学者。我陷入角色、声明和用户关系中。
我有一个用户 Ben,用户属于 Admin 角色。 Admin 角色在数据库中拥有 view-page 和 edit-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) returns 空声明?
有什么建议吗?
Why userManager.GetClaimsAsync(user) returns empty claims ?
因为UserManager.GetClaimsAsync(user)
查询了UserClaims
table。同为
RoleManager.GetClaimsAsync(role)
查询 RoleClaims
table.
但根据 ASP.NET Identity Core 中的设计,当用户是某个角色的成员时,他们会自动继承该角色的声明。您可以检查 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));
}
}
}
}
}
这让我可以 Update/Delete 一个具有声明的角色,并将这些更改传递给用户 Re-Issued/Removed ,这些用户被分配了角色和声明。但是,我仍在寻找更多 elegant/easier 代码更少的东西。