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
相关产品推荐
相关产品推荐

