You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Identity角色权限异常:已分配Administrator角色仍返回403 Forbidden

问题:JWT角色授权返回403错误,已确认用户分配对应角色

我正在开发一款应用,目前已实现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方法只添加了基础用户信息,未注入角色数据。

具体解决步骤:

  1. 修改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>,现在依赖注入会自动处理)。

  2. 验证Token包含角色信息
    重新登录获取新Token后,用JWT解码工具(或Postman的Token解码功能)检查Payload,确认包含role字段且值为Administrator。

  3. 可选:使用自定义授权策略
    如果你已定义了RequireAdministratorRole策略,也可以直接在控制器上使用[Authorize(Policy = "RequireAdministratorRole")],效果与[Authorize(Roles = "Administrator")]一致。

内容的提问来源于stack exchange,提问作者Dren Ibrahimi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 07:25:25