高效检查角色声明

本文关键字:声明 角色 检查 高效 | 更新日期: 2023-09-27 18:32:36

我正在开发一个 Asp.NET 的MVC5 Web应用程序(.NET 4.6),我需要向一组具有特定声明的用户显示一些额外的HTML行。我已经看到了一些冗长的解决方案,但我更喜欢保持简短,所以我想出了这个

@{
    if (System.Security.Claims.ClaimsPrincipal.Current.Claims.ToList().FirstOrDefault(c => c.Type == "role" && c.Value == "AwesomeUserRole") != null) {
        <!-- my HTML goes here -->
    }
 }

这是检查经过身份验证的用户声明的好方法,还是有最佳做法可以遵循?任何更清洁/更有效的解决方案也受到欢迎。

高效检查角色声明

因为 ASP.NET 中的所有Identity对象现在都是ClaimsIdentity,所以您始终可以将当前IPrincipal转换为ClaimsIdentity

((System.Security.Claims.ClaimsIdentity)User.Identity).HasClaim("role", "AwesomeUserRole")

但实际上最简单的方法是使用User.IsInRole("AwesomeUserRole")

只要未更改默认配置,具有role类型的声明就会自动馈送到线程主体的角色集合中。

如果需要检查除角色之外的其他声明类型,我通常会为包装声明检查的IPrincipal创建一组扩展方法:

public static bool CanDoX(this IPrincipal principal)
{
    return ((ClaimsIdentity)principal.Identity).HasClaim(claimType, claimValue);
}

扩展方法的好处是,您可以检查任何类型的声明并返回它们可能包含的任何值,而不仅仅是声明是否存在。

请记住

,主体可以有多个与之关联的标识,例如,您已使用 Windows 身份验证进行身份验证,但随后添加了包含数据库中声明的自定义标识。

因此,任何声明检查都可能需要查看所有身份,这里有几种扩展方法会有所帮助

public static bool ClaimExists(this IPrincipal principal, string claimType)
{
    var ci = principal as ClaimsPrincipal;
    if (ci == null)
    {
        return false;
    }
    var claim = ci.Claims.FirstOrDefault(x => x.Type == claimType);
    return claim != null;
}
public static bool HasClaim(this IPrincipal principal, string claimType,
                            string claimValue, string issuer = null)
{
    var ci = principal as ClaimsPrincipal;
    if (ci == null)
    {
        return false;
    }
    var claim = ci.Claims.FirstOrDefault(x => x.Type == claimType
                                         && x.Value == claimValue
                                         && (issuer == null || x.Issuer == issuer));
    return claim != null;
}