如何将 List<Claim> 转换为 Dictionary<string,object>?

Leo*_*que 1 c# dictionary list

我收到了使用 jwt 令牌的声明

获取有效声明并生成 Jwt 令牌

var claims = await GetValidClaims(users);
Token = GenerateJwtToken(users, claims);
Run Code Online (Sandbox Code Playgroud)

生成JwtToken方法

private string GenerateJwtToken(ApplicationUser user, List<Claim> claims)
{
    var dicClaim = new Dictionary<string,object>();
    ...
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Claims = dicClaim,   // <<<<<<<<<< this Claims is Dictionary<string,object>
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

获取有效索赔方法

private async Task<List<Claim>> GetValidClaims(ApplicationUser user)
{
    IdentityOptions _options = new IdentityOptions();
    var claims = new List<Claim>
    {
        new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
        new Claim(_options.ClaimsIdentity.UserIdClaimType, user.Id.ToString()),
        new Claim(_options.ClaimsIdentity.UserNameClaimType, user.UserName)
    };
    var userClaims = await _userManager.GetClaimsAsync(user);
    var userRoles = await _userManager.GetRolesAsync(user);
    claims.AddRange(userClaims);
    foreach (var userRole in userRoles)
    {
        claims.Add(new Claim(ClaimTypes.Role, userRole));
        var role = await _roleManager.FindByNameAsync(userRole);
        if (role != null)
        {
            var roleClaims = await _roleManager.GetClaimsAsync(role);
            foreach (Claim roleClaim in roleClaims)
            {
                claims.Add(roleClaim);
            }
        }
    }
    return claims;
}
Run Code Online (Sandbox Code Playgroud)

在这一行:Claims = dicClaim, // <<<<<<<<<< this Claims is Dictionary<string,object>

但我不知道如何将列表转换为字典

我已经尝试过这样的事情:

claims.ToDictionary(x=>x,x=>x.Value)

claims.ToDictionary(x=>x.Value,x=>x)

SecurityTokenDescriptor 在此输入图像描述

Dmi*_*nko 6

为了创建字典,我们必须为其定义唯一的。 Key假如说

  1. 我们希望我们的钥匙是这样Type或者至少Type
  2. 索赔可以重复

我们可以这样解决:

  1. GroupType(所需密钥)的所有声明
  2. 1如果组中只有一个声明,则使用ValueasKey
  3. 如果没有,让我们生成Type_1, Type_2, ..., Type_N Keys

代码

var dicClaim = claims
  .GroupBy(claim => claim.Type) // Desired Key
  .SelectMany(group => group
     .Select((item, index) => group.Count() <= 1
        ? Tuple.Create(group.Key, item) // One claim in group
        : Tuple.Create($"{group.Key}_{index + 1}", item) // Many claims
      )) 
  .ToDictionary(tuple => tuple.Item1, tuple => tuple.Item2); 
Run Code Online (Sandbox Code Playgroud)

如果您想获得重复的Last索赔,例如,仅获得一次索赔,您可以使用以下代码来完成:

 var dicClaim = claims
   .GroupBy(claim => claim.Type) // Desired Key
   .ToDictionary(group => group.Key, group => group.Last());
Run Code Online (Sandbox Code Playgroud)