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

ASP.NET Core中[Authorize(Roles)]特性返回404错误,但自定义授权策略正常工作的问题求助

ASP.NET Core中[Authorize(Roles)]特性返回404错误,但自定义授权策略正常工作的问题求助

我在ASP.NET Core项目里已经初始化了带有User和Admin角色的用户,但当我使用[Authorize(Roles="User")]或者[Authorize(Roles="Admin")]特性时,接口返回的是HTTP 404 Not Found错误,而不是预期的200 OK、403 Forbidden(角色不符)或者401 Unauthorized(未携带JWT)。但如果用自定义的授权策略(比如[Authorize("UserPolicy")])就完全正常,这让我很困惑。

认证与授权配置代码

var jwtSettings = builder.Configuration.GetSection("Jwt");
builder.Services.AddAuthentication(options => {
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
    options.TokenValidationParameters = new TokenValidationParameters {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = jwtSettings["Issuer"],
        ValidAudience = jwtSettings["Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"])),
        RoleClaimType = ClaimTypes.Role
    };
});

builder.Services.AddAuthorization(options => {
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
        .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .Build();
    options.AddPolicy("UserPolicy", policy => policy
        .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .RequireRole("User"));
    options.AddPolicy("AdminPolicy", policy => policy
        .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .RequireRole("Admin"));
});

用户与角色初始化代码

async Task SeedAsync() {
    var userManager = services.GetRequiredService<UserManager<User>>();
    var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
    try {
        string[] rolenames = { "Admin", "User", "Manager" };
        foreach (var rolename in rolenames) {
            var result = await roleManager.FindByNameAsync(rolename);
            if (result == null) {
                await roleManager.CreateAsync(new IdentityRole(rolename));
            }
        }
        var user = new User {
            FullName = "Mohammed",
            Email = "mo@123.com",
            UserName = "Mohammed"
        };
        var results = await userManager.FindByEmailAsync(user.Email);
        if (results == null) {
            await userManager.CreateAsync(user, "Password123!");
        }
    } catch (Exception ex) {
        Console.WriteLine(ex.Message);
    }
}
await SeedAsync();

测试用控制器方法

// GET: api/category
[HttpGet]
[Authorize(Roles="User")]
public async Task<ActionResult<IEnumerable<CategoryDto>>> GetAll() {
    var categories = await _categoryService.GetAllAsync();
    return Ok(categories);
}

// GET: api/category/{id}
[HttpGet("{id}")]
[Authorize("AdminPolicy")]
public async Task<ActionResult<CategoryDto>> GetById(int id) {
    var category = await _categoryService.GetByIdAsync(id);
    if (category == null) return NotFound();
    return Ok(category);
}

测试情况说明

  • 第二个使用AdminPolicy的接口完全正常,能返回预期的200 OK、403 Forbidden或者401 Unauthorized
  • 第一个用[Authorize(Roles="User")]的接口无论请求是否合法,都返回404错误;但改成[Authorize(Policy="UserPolicy")]就正常工作
  • 我本来想通过[Authorize(Roles="User,Admin")]这种方式实现多角色可选的授权,避免为每种角色组合创建单独策略,但现在这个问题卡住了
  • 临时解决方法:把[Authorize(Roles="Admin")]改成[Authorize(AuthenticationSchemes="Bearer", Roles="Admin")]就能正常工作,但我不想每次都手动指定认证方案,希望能直接用Roles参数完成授权

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 12:59:32