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

时间:2019-07-29 14:36:12

标签: c#

我声称要戴上jwt令牌

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

var claims = await GetValidClaims(users);
Token = GenerateJwtToken(users, claims);

GenerateJwtToken方法

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>
        ...
    }
}

GetValidClaims方法

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;
}

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

但是我不知道如何将List转换为Dictionary

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

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

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

SecurityTokenDescriptor enter image description here

1 个答案:

答案 0 :(得分:2)

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

  1. 我们希望我们的密钥是 ,例如Type或至少 start Type
  2. 索赔可以重复

我们可以这样解决:

  1. Group通过Type的所有声明(所需密钥)
  2. 如果一个组中只有1个声明,请将Value用作Key
  3. 否则,我们生成Type_1Type_2,...,Type_N Key s

代码

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

如果在重复声明中,您只想获得Last,则可以使用以下代码来实现:

 var dicClaim = claims
   .GroupBy(claim => claim.Type) // Desired Key
   .ToDictionary(group => group.Key, group => group.Last());