我想知道是否有一种方法可以从索赔中删除重复项
这是我的提取代码:
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
foreach (Delegation d in delegations)
{
List<string> delegateRoles = await (from r in _dbContext.Roles
where (del.DelegatedId == user.UserId)
select r.RoleName).Distinct().ToListAsync();
foreach (string role in delegateRoles)
{
if (DelegatorUserRoles.Contains(role))
{
identity.AddClaim(new Claim("DelegatedRole", role));
}
}
}
问题是我可以有多个具有相同角色的委托,所以我想删除重复项
我知道这是一个老问题,但对于在某个时候偶然发现这个问题的人(就像我一样)。
删除已经添加的重复项的具体方法?不,它不存在。你自己可以做吗?绝对。
我做了什么:
public sealed class UserClaimsPrincipalFactory : UserClaimsPrincipalFactory<User, Role>
{
// ...
protected override async Task<ClaimsIdentity> GenerateClaimsAsync(User user)
{
ClaimsIdentity identity = await base.GenerateClaimsAsync(user);
if (identity.Claims is not IList<Claim> claimList)
{
claimList = identity.Claims.ToList();
}
// Remove duplicate capabilities
var duplicateCapabilityClaims = claimList
.Where(x => x.Type == ClaimTypes.Capabilities)
.GroupBy(x => x.Value)
.Where(x => x.Count() > 1)
.SelectMany(x => x.SkipLast(1));
foreach (var claim in duplicateCapabilityClaims)
{
identity.RemoveClaim(claim);
}
return identity;
}
}
这个是针对 ASP.NET Core Identity 生成的声明,它只是转储角色在其声明中的所有内容,可能会重复相同的功能两次或更多次。我无法控制在基本
GenerateClaimsAsync
调用中实际放入声明中的内容。
另一方面,在您的代码示例中,您似乎可以使用
HashSet<string>
来跟踪实际不同的角色,类似于:
List<string> delegateRoles = await (from r in _dbContext.Roles
where (del.DelegatedId == user.UserId)
select r.RoleName).Distinct().ToListAsync();
HashSet<string> uniqueDelegateRoles = delegateRoles.ToHashSet();
foreach (string role in uniqueDelegateRoles)
{
if (DelegatorUserRoles.Contains(role)) // Not sure what this is as the snippet is incomplete, but keeping it
{
identity.AddClaim(new Claim("DelegatedRole", role));
}
}
那么您不应再有此特定索赔类型的任何重复项。
您的问题询问是否可以删除重复项(是的;不是直接开箱即用),但就您而言,最好不要首先添加重复的声明(因此,第二个示例) .