【问题标题】:ASP.NET Core JWTAuthentication and Authorize Role ClaimsASP.NET Core JWTAuthentication 和授权角色声明
【发布时间】:2023-03-19 00:12:01
【问题描述】:

我已经成功地让 JWT 令牌身份验证在我的 API 上运行,但是,我正在努力将角色声明集成到身份验证过程中。

我想要实现的是能够将以下内容添加到我的控制器中的调用中,并让网站自动针对经过身份验证的用户检查角色声明:

[Authorize(Roles = "SiteAdmin")]

这是生成 JWT Token 的代码:

    private string GenerateJwtToken(UserDto user)
    {
        // generate token that is valid for 7 days
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new[] { new Claim("userAccountId", user.UserAccountId.ToString()) }),
            Expires = DateTime.UtcNow.AddHours(_appSettings.JwtExpiryHours),
            SigningCredentials =
                new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }

我已尝试在此处遵循本指南 (https://www.jerriepelser.com/blog/using-roles-with-the-jwt-middleware/),并将上述功能更改为以下内容:

    private async Task<string> GenerateJwtToken(UserDto user)
    {
        // generate token that is valid for 7 days
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new[] { new Claim("userAccountId", user.UserAccountId.ToString()) }),
            Expires = DateTime.UtcNow.AddHours(_appSettings.JwtExpiryHours),
            SigningCredentials =
                new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
            Claims = await FetchClaims(user.UserAccountId)
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }

    private async Task<Dictionary<string, object>> FetchClaims(int userId)
    {
        var userPermissions = await GetUserPermissionsByUserId(userId);
        var userClaims = new Dictionary<string, object>();

        foreach (var userPermission in userPermissions)
        {
            userClaims.Add("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", userPermission.PermissionName);
        }

        return userClaims;
    }

虽然从理论上讲,上述内容在我的脑海中是有道理的,但我不能添加多个角色声明,因为在向字典中添加 userClaim 时,它会添加一个重复的键。

我一定是误解了这个实现是如何工作的,任何帮助都将不胜感激。

【问题讨论】:

  • 您添加了角色声明,但值看起来像权限?这令人困惑。您可以尝试通过逗号分隔的角色名称添加多个角色(当然,用户声明角色只有一个键)。

标签: c# asp.net-core jwt


【解决方案1】:

我也不确定“权限”是怎么回事,但假设你正在获得角色......

您可以通过这种方式简单地重构它,并将声明列表添加到您传递给ClaimsIdentity的集合中:

        private async Task<string> GenerateJwtToken(UserDto user)
        {
            // generate token that is valid for 7 days
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
            var claims = new List<Claim>(await FetchClaims(user.UserAccountId)) {
                new Claim("userAccountId", user.UserAccountId.ToString())
            };
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Expires = DateTime.UtcNow.AddHours(_appSettings.JwtExpiryHours),
                SigningCredentials =
                    new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }

        private async Task<IEnumerable<Claim>> FetchClaims(int userId)
        {
            var userPermissions = await GetUserPermissionsByUserId(userId);

            return userPermissions
                .Select(x => new Claim(ClaimTypes.Role, x.PermissionName));
        }

(如果需要,您也可以使用JwtSecurityToken 代替SecurityTokenDescriptor;它直接接受IEnumerable&lt;Claim&gt;。)

我承认我已经有一段时间没有使用角色了,所以如果它不起作用,请告诉我。但是从快速谷歌搜索来看,向令牌添加多个角色声明似乎是合法的。 [编辑:我测试了添加多个角色声明并对它们进行授权,它对我有用。]

【讨论】:

  • 效果很好,感谢您抽出宝贵时间完成所有这些工作!非常感谢。
  • 嗨,appSettings.Secret 在哪里,请粘贴开发环境的示例。
猜你喜欢
  • 2021-09-04
  • 2020-05-18
  • 2018-02-10
  • 2017-12-01
  • 1970-01-01
  • 2017-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多