ASP.NET Identity角色权限异常:已分配Administrator角色仍返回403 Forbidden
我正在开发一款应用,目前已实现Identity API。登录/注册功能正常,均会返回带Token的用户信息。在Postman中传递JWT Token时,控制器上的[Authorize]特性可正常工作。然而,当添加[Authorize(Roles = "Administrator")]特性后,尽管已确认用户被分配了"Administrator"角色,仍会收到403响应。
相关代码
UserController中的方法
[Authorize(Roles = ("Administrator"))] [HttpGet] public async Task<ActionResult<IEnumerable<AppUser>>> GetUsers() { return await _userManager.Users.ToListAsync(); }
TokenService类代码
public class TokenService { public readonly IConfiguration _config; public TokenService(IConfiguration config) { _config = config; } public string CreateToken(AppUser user) { var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Email, user.Email) }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["TokenKey"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.Now.AddDays(7), SigningCredentials = creds }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } }
Program.cs关键代码片段
private static async Task Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(opt => { // 所有端点默认需要认证,除了标记[AllowAnonymous]的 var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); opt.Filters.Add(new AuthorizeFilter(policy)); }); // ... 其他服务注册代码省略 ... builder.Services.AddDefaultIdentity<AppUser>().AddRoles<IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>(); builder.Services.AddIdentityServices(builder.Configuration); builder.Services.AddAuthorization(options => { options.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("Administrator")); }); // ... 中间件配置及其他代码省略 ... app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); await app.RunAsync(); }
问题原因及解决步骤
问题核心是JWT Token中未包含用户的角色声明,ASP.NET Core的角色授权依赖Token中的角色Claim进行验证,而当前TokenService.CreateToken方法只添加了基础用户信息,未注入角色数据。
具体解决步骤:
修改TokenService,添加角色Claim
需要在Token生成逻辑中获取用户的角色列表,并添加到Claim集合中。同时要注入UserManager<AppUser>来读取用户角色:public class TokenService { public readonly IConfiguration _config; public readonly UserManager<AppUser> _userManager; // 注入UserManager依赖 public TokenService(IConfiguration config, UserManager<AppUser> userManager) { _config = config; _userManager = userManager; } // 改为异步方法,因为GetRolesAsync是异步操作 public async Task<string> CreateToken(AppUser user) { var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Email, user.Email) }; // 获取用户所有角色并添加到Claims var roles = await _userManager.GetRolesAsync(user); foreach (var role in roles) { claims.Add(new Claim(ClaimTypes.Role, role)); } var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["TokenKey"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.Now.AddDays(7), SigningCredentials = creds }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } }同时要在Program.cs中确保TokenService的注册正确(如果之前是
AddScoped<TokenService>,现在依赖注入会自动处理)。验证Token包含角色信息
重新登录获取新Token后,用JWT解码工具(或Postman的Token解码功能)检查Payload,确认包含role字段且值为Administrator。可选:使用自定义授权策略
如果你已定义了RequireAdministratorRole策略,也可以直接在控制器上使用[Authorize(Policy = "RequireAdministratorRole")],效果与[Authorize(Roles = "Administrator")]一致。
内容的提问来源于stack exchange,提问作者Dren Ibrahimi

