`ClaimsPrincipal.IsInRole` 在声明中期望什么?
What does `ClaimsPrincipal.IsInRole` expect in the claim?
我有一个索赔 groups
。当我设置 TokenValidationParameters
时,我将 RoleClaimType
设置为 groups
。
当声明通过时,groups
声明的值如下:
"something,some other thing,more things,other other things"
但是当我打电话时:
User.IsInRole("some other thing");
结果是False
。
IsInRole
在该声明中期望什么?
意思是它需要分号分隔、逗号分隔(这似乎不起作用)、space 分隔或单个值(不确定它怎么可能是 "in" 检查是否这是一个单一的价值。)
您正在尝试使用声明,但您正在使用 role
的方法验证它们。
What does IsInRole expect in that claim?
User.IsInRole(roleName)
方法检查 User
是否在应用程序中具有指定的角色 roleName
。
实际的方法结构是这样的:
public bool IsInRole (string role);
因此 "some other thing"
必须是在您的应用程序中注册的 role
,并且 User
必须被授予该角色才能使方法 return 为真。
你可以阅读更多here
IsInRole
希望声明包含您要查找的值。
这就是为什么它不适用于您的情况。
您可以做的是像这样进行声明转换:
public class AzureAdGroupsSplitClaimTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var identities = principal.Identities;
if (identities == null)
{
return Task.FromResult(principal);
}
var result = new List<ClaimsIdentity>();
var groupsClaimSplit = false;
// Iterate each identity the user may have, make sure to keep all of them
foreach (var identity in identities)
{
var groupClaims = identity.FindAll("groups").ToList();
if (groupClaims.Count != 1 || !groupClaims[0].Value.Contains(','))
{
// groupClaims.Count == 0: Identity does not have groups
// groupClaims.Count > 1: Identity has more than one groups claim, already split
// The only groups claim does not contain a comma: Identity has one group, no need to split
result.Add(identity);
continue;
}
var claim = groupClaims[0];
var groups = claim.Value.Split(',', StringSplitOptions.RemoveEmptyEntries);
var claims = groups.Select(s => new Claim("groups", s));
var updatedIdentity = new ClaimsIdentity(identity, claims);
result.Add(updatedIdentity);
groupsClaimSplit = true;
}
// Nothing was done to the original identities, may as well just return the original principal
if (!groupsClaimSplit)
{
return Task.FromResult(principal);
}
return Task.FromResult(new ClaimsPrincipal(result));
}
}
然后在服务集合中注册:
services.AddSingleton<IClaimsTransformation, AzureAdGroupsSplitClaimTransformation>();
现在您应该为只有一个值的用户获得额外的组声明。
然后您的角色检查应该起作用。
虽然为此目的使用 IsInRole 有点奇怪,
你也可以使用 User.HasClaim("groups", "your-group-id")
.
我有一个索赔 groups
。当我设置 TokenValidationParameters
时,我将 RoleClaimType
设置为 groups
。
当声明通过时,groups
声明的值如下:
"something,some other thing,more things,other other things"
但是当我打电话时:
User.IsInRole("some other thing");
结果是False
。
IsInRole
在该声明中期望什么?
意思是它需要分号分隔、逗号分隔(这似乎不起作用)、space 分隔或单个值(不确定它怎么可能是 "in" 检查是否这是一个单一的价值。)
您正在尝试使用声明,但您正在使用 role
的方法验证它们。
What does IsInRole expect in that claim?
User.IsInRole(roleName)
方法检查 User
是否在应用程序中具有指定的角色 roleName
。
实际的方法结构是这样的:
public bool IsInRole (string role);
因此 "some other thing"
必须是在您的应用程序中注册的 role
,并且 User
必须被授予该角色才能使方法 return 为真。
你可以阅读更多here
IsInRole
希望声明包含您要查找的值。
这就是为什么它不适用于您的情况。
您可以做的是像这样进行声明转换:
public class AzureAdGroupsSplitClaimTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var identities = principal.Identities;
if (identities == null)
{
return Task.FromResult(principal);
}
var result = new List<ClaimsIdentity>();
var groupsClaimSplit = false;
// Iterate each identity the user may have, make sure to keep all of them
foreach (var identity in identities)
{
var groupClaims = identity.FindAll("groups").ToList();
if (groupClaims.Count != 1 || !groupClaims[0].Value.Contains(','))
{
// groupClaims.Count == 0: Identity does not have groups
// groupClaims.Count > 1: Identity has more than one groups claim, already split
// The only groups claim does not contain a comma: Identity has one group, no need to split
result.Add(identity);
continue;
}
var claim = groupClaims[0];
var groups = claim.Value.Split(',', StringSplitOptions.RemoveEmptyEntries);
var claims = groups.Select(s => new Claim("groups", s));
var updatedIdentity = new ClaimsIdentity(identity, claims);
result.Add(updatedIdentity);
groupsClaimSplit = true;
}
// Nothing was done to the original identities, may as well just return the original principal
if (!groupsClaimSplit)
{
return Task.FromResult(principal);
}
return Task.FromResult(new ClaimsPrincipal(result));
}
}
然后在服务集合中注册:
services.AddSingleton<IClaimsTransformation, AzureAdGroupsSplitClaimTransformation>();
现在您应该为只有一个值的用户获得额外的组声明。
然后您的角色检查应该起作用。
虽然为此目的使用 IsInRole 有点奇怪,
你也可以使用 User.HasClaim("groups", "your-group-id")
.