C# 有效地检查角色声明

C# 有效地检查角色声明,c#,asp.net,asp.net-mvc,authentication,claims,C#,Asp.net,Asp.net Mvc,Authentication,Claims,我正在开发一个Asp.NET MVC5 web应用程序(.NET 4.6),我需要向一组具有特定声明的用户显示一些额外的HTML行。我见过一些冗长的解决方案,但我更喜欢保持简短,所以我想出了这个 @{ if (System.Security.Claims.ClaimsPrincipal.Current.Claims.ToList().FirstOrDefault(c => c.Type == "role" && c.Value == "AwesomeUserRole

我正在开发一个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 -->
    }
 }
@{
if(System.Security.Claims.ClaimsPrincipal.Current.Claims.ToList().FirstOrDefault(c=>c.Type==“role”&c.Value==“AwesomeUserRole”)!=null){
}
}

这是一种检查经过身份验证的用户声明的好方法,还是有一种最佳实践可以遵循?任何更干净/更高效的解决方案都是受欢迎的。

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

((System.Security.Claims.ClaimsIdentity)User.Identity).HasClaim("role", "AwesomeUserRole")
但实际上,只使用
User.IsInRole(“AwesomeUserRole”)

只要您没有更改默认配置,类型为
role
的声明就会自动输入到线程主体的roles集合中

如果您需要检查角色之外的其他索赔类型,我通常会为
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;
}

((System.Security.Claims.ClaimsIdentity)User.Identity)。HasClaim(“角色”、“miAdmin”)和User.IsInRole(“miAdmin”)不会为我返回相同的值。第一个对我来说是正确的。不确定User.IsInRole(“miAdmin”)为什么不工作。请检查标识是否使用“role”作为其角色声明类型,默认为uri
,具有角色类型的声明将自动馈送到线程主体的角色集合中
这一行确实很有帮助。谢谢