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

ASP.NET Core中带[Authorize(Roles)]的接口调用出现403权限错误

JWT角色授权403错误排查与修复

问题描述

实现简单JWT令牌授权后,无角色限制的接口可正常调用,但给方法添加特定角色访问限制后,调用出现403权限错误。已通过RoleService在数据库中注册角色,但问题仍未解决。


核心错误点及修复方案

1. Token生成时角色Claim构造错误

在JWTService.GenerateToken方法中,Claim的参数传递逻辑错误,导致角色信息未被正确写入Token:
原错误代码:

var claims = new List<Claim> { new Claim(ClaimsIdentity.DefaultNameClaimType, name, ClaimsIdentity.DefaultRoleClaimType, role) };

这里错误地将角色Claim类型作为Issuer参数传递,正确做法是单独添加角色Claim:
修正后代码:

public string GenerateToken(string name, string role)
{
    var claims = new List<Claim>
    {
        new Claim(ClaimsIdentity.DefaultNameClaimType, name),
        new Claim(ClaimsIdentity.DefaultRoleClaimType, role) // 单独添加角色类型的Claim
    };

    var jwt = new JwtSecurityToken(
        issuer: AuthOptions.ISSUER,
        audience: AuthOptions.AUDIENCE,
        claims: claims,
        expires: DateTime.Now.AddSeconds(20),
        signingCredentials: new SigningCredentials(AuthOptions.GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256)
    );
  
    return new JwtSecurityTokenHandler().WriteToken(jwt);
}

2. 角色名称与授权规则不匹配

  • 控制器中使用[Authorize(Roles = "admin")],但RoleService中创建的角色是"administrator"、"cook"、"waiter",角色名称完全不匹配,直接导致403。
  • Program.cs中的授权策略逻辑错误,原代码要求存在名为"admin"的Claim,而非校验角色:
    原错误策略:
option.AddPolicy("admin", policyBuilder => policyBuilder.RequireClaim("admin", "waiter", "cook"));

修正后授权策略:

builder.Services.AddAuthorization(option =>
{
    // 仅允许管理员访问的策略
    option.AddPolicy("AdministratorOnly", policyBuilder => policyBuilder.RequireRole("administrator"));
    // 允许管理员/服务员/厨师访问的策略
    option.AddPolicy("StaffAccess", policyBuilder => policyBuilder.RequireRole("administrator", "waiter", "cook"));
});

修正后控制器注解:

[HttpGet]
[Authorize(Policy = "AdministratorOnly")] // 或直接用[Authorize(Roles = "administrator")]
[Route("getSecretInfo")]
public IActionResult GetSecretInfo()
{
    return Ok("QWERTY");
}

3. 中间件顺序错误

Program.cs中UseAuthorization和UseCors顺序颠倒,CORS需要在授权前处理跨域请求:
原错误顺序:

app.UseAuthorization();
app.UseCors(Origins);

修正后顺序:

app.UseCors(Origins);
app.UseAuthorization();

4. Identity DbContext冗余配置

RestarauntTPDBIdentityDBContext继承IdentityDbContext<IdentityUser>后,无需额外定义DbSet<IdentityRole>,且OnConfiguring方法可删除(已在Program.cs中配置连接字符串):
修正后DbContext:

public class RestarauntTPDBIdentityDBContext : IdentityDbContext<IdentityUser>
{
    public RestarauntTPDBIdentityDBContext(DbContextOptions<RestarauntTPDBIdentityDBContext> options) : base(options)
    {
    }
}

验证步骤

  1. 生成Token后,通过JWT解析工具确认Token中包含正确的角色Claim(如"role": "administrator")。
  2. 确认登录时传递给GenerateToken的role参数与数据库中角色名称一致。
  3. 检查数据库中用户是否已被正确分配对应角色(若使用Identity用户角色关联)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:04:53