Asp.Net Core WebApi中Authorize角色授权返回403问题排查
问题根源:JWT Token中未包含用户角色信息
我一眼就看出问题出在你的JWT生成逻辑上!你当前的GenerateJwtToken方法只添加了基础的用户标识Claim,但没有把用户的角色信息写入Token。这就导致ASP.NET Core的角色授权中间件无法从Token中识别出用户的admin角色,所以带[Authorize(Roles = Roles.AdminRole)]的接口会返回403。
而你的GetRoles方法能正常工作,是因为它没有依赖Token里的角色信息——而是通过_userManager.IsInRoleAsync直接从数据库查询用户的角色,所以不管Token里有没有角色数据,都能正确判断用户是否是管理员。
解决方案:在JWT中添加角色Claim
修改你的GenerateJwtToken方法,在生成Claims集合时,先获取用户的所有角色,然后逐个添加到Claim列表中:
private async Task<object> GenerateJwtToken(IdentityUser user) { var claims = new List<Claim> { new Claim(JwtRegisteredClaimNames.Sub, user.UserName), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(ClaimTypes.NameIdentifier, user.Id) }; // 新增:获取用户角色并添加到Claims var userRoles = await _userManager.GetRolesAsync(user); foreach (var role in userRoles) { claims.Add(new Claim(ClaimTypes.Role, role)); } var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpireDays"])); var token = new JwtSecurityToken( _configuration["JwtIssuer"], _configuration["JwtIssuer"], claims, expires: expires, signingCredentials: creds ); return new JwtSecurityTokenHandler().WriteToken(token); }
额外注意点
- 确保
Roles.AdminRole的值和你创建的角色名称完全一致(大小写敏感)。 - 你已经在Startup中添加了
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();,这能避免默认Claim类型映射的干扰,让角色Claim能被正确识别,所以这部分不需要修改。 - 不需要在请求头添加其他内容,只要重新生成包含角色信息的Token,用这个新Token请求
CreateRole接口就可以正常访问了。
内容的提问来源于stack exchange,提问作者Nikita Goncharuk
相关产品推荐
相关产品推荐

