角色列表的 Where 子句 asp.net mvc 身份

Where clause for list of roles asp.net mvc identity

我有以下变量选择当前登录用户所在的所有角色:

var roles = ((ClaimsIdentity)User.Identity).Claims
    .Where(c => c.Type == ClaimTypes.Role)
    .Select(c => c.Value);

我希望能够过滤此列表,仅包含开头为 Club 且结尾为 Admin 的角色。

角色由单词 Club、clubs Id 和 Admin 组成。

我试过向其中添加 contains 子句,但没有成功。

var roleFilter = string.Format("Club{0}Admin", clubId);    
var roles = ((ClaimsIdentity)User.Identity).Claims
                .Where(c => c.Type == ClaimTypes.Role && roleFilter.Equals(c.Value)
                .Select(c => c.Value);

可选地,如果需要,您可以在相等性检查中使用 StringComparison IgnoreCase 选项。

感谢@lyz 的回答:

            var roles = ((ClaimsIdentity)User.Identity).Claims
            .Where(c => c.Type == ClaimTypes.Role && c.Value.StartsWith("Club") && c.Value.EndsWith("Admin"))
            .Select(c => c.Value);

当然,您可以使用 Claims,但是还有其他一些东西(而且更简单)可以获取当前用户角色。

第一个是使用UserManager<TUser> class,这是一个实例IUserManager<TUser>接口。当您创建默认项目时,它在您的控制器中存储为 属性。 class 许多有用的方法可以处理用户帐户本身(创建、编辑、删除)以及用户角色(分配、取消分配和检索)。此外,使用此管理器,您可以 1000% 确定,如果有人在 1 秒前更改了用户角色,您将获得合适的用户角色 always

第二个是使用 User 控制器 属性 的内置 IsInRole(string role) 方法。 returns 如果当前登录的用户具有指定的角色则为真,否则为假。这种方法有点 "unstable" 因为它依赖于 User 数据,它是 IPrincipal 的一个实例,并在您的用户登录时分配。如果他当前已登录,则更改当前用户角色可以发生只有在您向该用户提供注销然后再次登录后。这是因为您需要将 IdentityUser 实例的实例重新分配给当前 IPrincipal 实例。此外,对于 ClaimsIdentityClaims 数组也是如此。但是,如果您确定这在您的系统中是不可能的 - 您可以忽略它。

此外,如果您在角色枚举中定义了您的角色,最好为 User 创建您自己的扩展方法,它将采用您的角色枚举值,而不是在每次调用内置时调用 ToString() IsInRole():

public static bool IsInRole(this IPrincipal principal, RolesEnum value)
{
    return principal.IsInRole(value.ToString());
}

如果你愿意,你也可以用同样的方式创建你自己的辅助方法来检查你的角色。

如果您更喜欢使用 LINQ 查询,只需将 Where 表达式替换为:

.Where(c => c.Type == ClaimTypes.Role && c.Value.StartsWith(startValeu) && c.Value.EndsWith(endValue))