ChatGPT解决这个技术问题 Extra ChatGPT

asp.net identity 获取登录用户的所有角色

我按照this教程创建了一个基于角色的菜单。在该页面的某些地方,您会看到这行代码:

String[] roles = Roles.GetRolesForUser();

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

它仍然很新,没有太多可找到的。

.NET Core 的声明和身份的一个很好的解释:andrewlock.net/introduction-to-authentication-with-asp-net-core(不是我的)
选择的答案并不完全正确。查看答案stackoverflow.com/a/63324519/2000301

A
Anthony Chu

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();

根据此文档 msdn.microsoft.com/en-us/library/…ClaimTypes 中没有 Role。我需要添加它还是什么?
ASP.NET 标识使用 System.Security.Claims.ClaimTypes msdn.microsoft.com/en-us/library/…。此外,ClaimsIdentity 对象还有一个包含相同值的 RoleClaimType 属性,您可以使用它来代替。
您能否更新您的答案以向我展示代码中的外观?尝试了几种方法,但我没有看到 RoleClaimType
也许只是事情在 2 年内发生了变化,但这似乎并不正确。我刚刚查看了我的数据库(由 EF 创建的表),在 AspNetUserRoles 表中有一条记录,但在 AspNetUserClaims 表中没有相应的记录,因此在将用户添加到角色时不一定会添加声明。
(from c in ((ClaimsIdentity)User.Identity).Claims where c.Type.Equals("role") select c.Value).ToArray() //因为请求数组
L
LawMan

这是上述解决方案的扩展方法。

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

如何访问它?
这是“System.Security.Claims.ClaimsIdentity”对象的扩展方法。
A
Amal K

SignInManager 获取身份用户后,在 UserManager 上调用 GetRolesAsync 并将身份用户作为参数传递。

它将返回身份用户已注册的角色列表。

var rolesList = await userManager.GetRolesAsync(identityuser).ConfigureAwait(false);

选择的答案是针对索赔而不是要求角色的 OP 的答案 - 这回答了 OP
A
Abdul Rahim

不要使用 @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?在哪里使用?
u
ubi

我认为任何答案都不完全正确,因为它们都采用登录用户的主要身份。 User 是一个 ClaimsPrincipal,可以有多个身份(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 令牌接收身份时,该令牌提供使用自定义声明名称作为角色声明类型的能力。