ASP.NET身份验证:获取已登录用户的所有角色

87

我为角色创建了基于菜单,其内容遵循教程。在该页面的某个地方,您会看到以下代码行:

String[] roles = Roles.GetRolesForUser();

它返回当前登录用户的所有角色。我想知道如何在新的ASP.NET身份验证系统中实现这一点?

它仍然很新,关于它的资料不多。


.NET Core中关于Claims和Identity的很好的解释:http://andrewlock.net/introduction-to-authentication-with-asp-net-core(非本人)。 - PaulCo
选择的答案并不完全正确。请参考答案 https://dev59.com/VWEi5IYBdhLWcg3wFokL#63324519 - ubi
7个回答

151

Controller.User.Identity 是一个 ClaimsIdentity。你可以通过检查声明来获取角色列表...

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

--- 更新 ---

进一步分解如下...

using System.Security.Claims;

// ........

var userIdentity = (ClaimsIdentity)User.Identity;
var claims = userIdentity.Claims;
var roleClaimType = userIdentity.RoleClaimType;
var roles = claims.Where(c => c.Type == ClaimTypes.Role).ToList();

// or...
var roles = claims.Where(c => c.Type == roleClaimType).ToList();

根据这份文档 http://msdn.microsoft.com/en-us/library/system.identitymodel.claims.claimtypes%28v=vs.110%29.aspx ,在 ClaimTypes 中没有 Role。我需要添加它或者做些什么吗? - Quoter
ASP.NET IdentityдҪҝз”ЁSystem.Security.Claims.ClaimTypes http://msdn.microsoft.com/en-us/library/system.security.claims.claimtypes(v=vs.110).aspxгҖӮжӯӨеӨ–пјҢ`ClaimsIdentity`еҜ№иұЎиҝҳе…·жңүдёҖдёӘ`RoleClaimType`еұһжҖ§пјҢе…¶дёӯеҢ…еҗ«зӣёеҗҢзҡ„еҖјпјҢжӮЁеҸҜд»ҘдҪҝз”ЁиҜҘеұһжҖ§д»ЈжӣҝгҖӮ - Anthony Chu
你能否更新你的回答,告诉我在代码中它会是什么样子?我尝试了几种方法,但是我没有看到 RoleClaimType - Quoter
2
也许只是两年间事情发生了变化,但这似乎不正确。我刚在我的数据库中查看了(由EF创建的表),AspNetUserRoles表中有一条记录,但AspNetUserClaims表中没有相应的记录,因此当用户被添加到角色时,并不一定会添加Claims。 - Rick
return ((ClaimsIdentity)User.Identity).Claims.Where(c => c.Type.Equals("role")).Select(c => c.Value).ToArray(); //因为要求返回数组 - JDPeckham
显示剩余2条评论

23

这是以上解决方案的一个扩展方法。

    public static List<string> Roles(this ClaimsIdentity identity)
    {
        return identity.Claims
                       .Where(c => c.Type == ClaimTypes.Role)
                       .Select(c => c.Value)
                       .ToList();
    }

如何访问它? - Tushar Kshirsagar
这是一个针对“System.Security.Claims.ClaimsIdentity”对象的扩展方法。 - LawMan

13
在从SignInManager中获取身份用户后,调用UserManager上的GetRolesAsync并将身份用户作为参数传递。它将返回身份用户已注册的角色列表。
var rolesList = await userManager.GetRolesAsync(identityuser).ConfigureAwait(false);

所选答案适用于索赔,而非 OP(原帖发布者)要求的角色 - 本答案回答了 OP 的问题。 - toy

6

我认为这些答案都不完全正确,因为它们都只考虑了已登录用户的主身份。UserClaimsPrincipal,可以有多个身份(ClaimsPrincipal.Identities属性)。而ClaimsPrincipal.Identity则是这些身份的主身份。所以要获取用户所有的角色,需要从所有身份中获取其角色。这也是内置的ClaimPrincipal.IsInRole(string roleName)方法的作用,即检查给定的roleName是否存在于任何一个身份中。

因此,获取所有角色的正确方式应该像这样:

    public static class ClaimsPrincipalExtensions

       public static IEnumerable<string> GetRoles(this ClaimsPrincipal principal)
        {
            return principal.Identities.SelectMany(i =>
            {
                return i.Claims
                    .Where(c => c.Type == i.RoleClaimType)
                    .Select(c => c.Value)
                    .ToList();
            });
        }
    }

并被用作

var roles = User.GetRoles()

此外,请注意在标识中使用的声明类型集 Identity.RoleClaimType,而不是静态声明类型ClaimTypes.Role。这是必要的,因为角色声明类型可以根据标识进行覆盖,例如当通过提供自定义声明名称作为角色声明类型的JWT令牌接收标识时。

三年后,这对于将 IPrincipal 传递给自定义授权方法效果完美。 - Tyler Kiser

4

不要使用 @using System.IdentityModel.Claims 命名空间,而是应该使用

@using System.Security.Claims

    @using System.Security.Claims
    @using Microsoft.AspNet.Identity
    @{      
       var claimsIdentity = User.Identity as System.Security.Claims.ClaimsIdentity;
       var customUserClaim = claimsIdentity != null ? claimsIdentity.Claims.FirstOrDefault(x => x.Type == "cutomType") : null;
       var customTypeValue= customUserClaim != null ? customUserClaim .Value : User.Identity.GetUserName();
       var roleOfUser = claimsIdentity != null ? claimsIdentity.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role).Value :"User";

}

这个问题应该要回答什么?谁在哪里使用 System.IdentityModel.Claims - Camilo Terevinto

0

请尝试以下操作:

var roles = user.Claims.Where(c => c.Type == ClaimTypes.Role).Select(x => x.Value).FirstOrDefault();

0

你也可以使用这样的语法:

var userClaims = User.Identity as System.Security.Claims.ClaimsIdentity;
var roles = userClaims.FindAll("http://schemas.microsoft.com/ws/2008/06/identity/claims/role").ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接