ASP.NET Core认证返回403 Forbidden问题排查求助
ASP.NET Core JWT授权返回403 Forbidden的排查与修复
你的配置存在几个关键缺失,导致授权失败,以下是具体问题和修复方案:
1. 缺少认证中间件
请求管道中仅添加了授权中间件,但未添加认证中间件。认证中间件负责解析JWT令牌、建立用户身份,必须在授权中间件之前执行。
修改代码:
#region enhance auth app.MapIdentityApi<IdentityUser>(); app.UseAuthentication(); // 新增这一行,必须放在UseAuthorization之前 app.UseAuthorization(); #endregion
2. JWT验证参数未配置
AddJwtBearer()未配置必要的验证参数,导致无法正确校验Identity Api生成的JWT令牌有效性。需要补充令牌验证规则:
修改认证服务配置:
builder.Services.AddAuthentication("Bearer") .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, // 从配置文件读取参数,需在appsettings.json中添加对应节点 ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; });
在appsettings.json中添加JWT配置:
"Jwt": { "Issuer": "YourAppIssuer", "Audience": "YourAppAudience", "Key": "YourStrongSigningKeyAtLeast16CharactersLong" }
3. 角色声明类型不匹配
ASP.NET Core Identity默认的角色声明类型是ClaimTypes.Role(对应URI:http://schemas.microsoft.com/ws/2008/06/identity/claims/role),但你自定义的Admin策略中使用的是"role"字符串作为声明类型,两者不匹配。
修复方案二选一:
方案A:修改策略使用默认角色声明类型
builder.Services.AddAuthorization(options => { options.AddPolicy("Admin", new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .RequireClaim(ClaimTypes.Role, "Admin") // 使用ClaimTypes.Role替代"role" .Build()); });
同时Action上改用策略授权:
[Authorize(Policy = "Admin")]
方案B:配置JWT将角色声明映射为role
在AddJwtBearer配置中添加声明映射:
options.TokenValidationParameters.RoleClaimType = "role";
这样[Authorize(Roles = Roles.Admin)]就能直接识别JWT中的role声明。
4. 确保Identity支持角色并生成包含角色的JWT
如果你的Identity未启用角色支持,生成的JWT不会包含角色声明。需修改Identity服务配置:
builder.Services.AddIdentityApiEndpoints<IdentityUser>() .AddRoles<IdentityRole>() // 启用角色支持 .AddEntityFrameworkStores<ApplicationDbContext>();
同时确保ApplicationDbContext继承自包含角色的上下文:
public class ApplicationDbContext : IdentityDbContext<IdentityUser, IdentityRole, string> { // 上下文实现代码 }
可以通过jwt.io解码获取到的AccessToken,确认令牌中是否包含角色声明,验证配置是否生效。
内容的提问来源于stack exchange,提问作者Juan Pablo Gomez
相关产品推荐
相关产品推荐

