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

.NET 8升级后ASP.NET Core Web API出现HTTP 403权限错误

.NET 8迁移后JWT角色验证导致403错误排查

维护的ASP.NET Core Web API项目采用Duende Identity Server、JWT Bearer令牌及基于角色的端点访问控制,升级至.NET 8(Microsoft.AspNetCore.App框架版本8.0.7)后出现HTTP 403错误。

项目中builder.ConfigureServices()的身份验证配置如下:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

builder.Services
       .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
       .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "id.YouDontNeedToKnow.example.com";

                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateAudience = false,
                        NameClaimType = "sub",
                        RoleClaimType = "role",
                        ValidTypes = [ "at+jwt" ]
                    };
                });

builder.Services
       .AddAuthorization(options =>
           {
               options.AddPolicy("Admin",
                                 AuthorisationPolicies.Admin());
           });

通过Swagger追踪端点请求,得到验证失败提示:

RolesAuthorizationRequirement:User.IsInRole must be true for one of the following roles: (Admin)

问题根源

User.IsInRole("Admin")验证不通过,说明JWT令牌中的角色声明未被ASP.NET Core正确识别为用户角色。核心原因是:

  • .NET中IsInRole方法默认检查**ClaimTypes.Role类型**的声明(对应URI:http://schemas.microsoft.com/ws/2008/06/identity/claims/role)
  • 当前配置中RoleClaimType = "role",仅将JWT里的role声明标记为角色类型,但未映射到.NET默认的角色Claim类型,导致授权逻辑无法识别。

解决方案

方案1:调整TokenValidationParameters映射

将RoleClaimType设置为.NET默认的ClaimTypes.Role,让JwtBearer自动将JWT中的role声明转换为.NET可识别的角色类型:

options.TokenValidationParameters = new TokenValidationParameters
{
    ValidateAudience = false,
    NameClaimType = ClaimTypes.NameIdentifier, // 可选:将sub映射为标准NameIdentifier
    RoleClaimType = ClaimTypes.Role,
    ValidTypes = [ "at+jwt" ]
};

方案2:修改授权策略匹配自定义声明

如果不想调整Claim类型映射,直接修改Admin策略,校验JWT中的role声明:

// 假设AuthorisationPolicies.Admin()的实现改为:
public static AuthorizationPolicy Admin()
{
    return new AuthorizationPolicyBuilder()
        .RequireClaim("role", "Admin")
        .Build();
}

方案3:手动转换角色声明(事件处理)

在JwtBearer配置中添加OnTokenValidated事件,手动将role声明转换为ClaimTypes.Role类型:

.AddJwtBearer("Bearer", options =>
{
    options.Authority = "id.YouDontNeedToKnow.example.com";

    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = false,
        NameClaimType = "sub",
        RoleClaimType = "role",
        ValidTypes = [ "at+jwt" ]
    };

    options.Events = new JwtBearerEvents
    {
        OnTokenValidated = context =>
        {
            var identity = context.Principal.Identity as ClaimsIdentity;
            if (identity != null)
            {
                // 提取所有role声明并转换为标准角色类型
                var roleClaims = identity.FindAll("role");
                foreach (var claim in roleClaims)
                {
                    identity.AddClaim(new Claim(ClaimTypes.Role, claim.Value));
                }
            }
            return Task.CompletedTask;
        }
    };
});

额外检查项

  1. 解码请求令牌,确认role声明存在且值为Admin
  2. 确认Duende Identity Server客户端配置中已正确授予Admin角色权限
  3. 确保Program.cs中中间件顺序正确:app.UseAuthentication()必须在app.UseAuthorization()之前

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:25:55