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

ASP.NET Core 6中JWT生成后Claims未填充致用户查询为空问题

问题根源

当你把AddIdentityCore替换为AddIdentity后,ASP.NET Core Identity会自动注册Cookie认证方案作为默认认证方式,直接覆盖了你的JWT认证配置。请求进入系统时,优先用Cookie解析ClaimsPrincipal,而非你生成的JWT令牌,导致User对象中没有JWT里包含的Email、Name等Claims,最终User.FindFirstValue(ClaimTypes.Email)返回null。

解决方案

方案1:强制设置JWT为默认认证方案

修改AddAuthentication的配置,明确指定默认的认证和挑战方案为JWT:

public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration config)
{
    services.AddIdentity<AppUser, AppRole>(opt =>
    {
        opt.Password.RequireNonAlphanumeric = false;
    })
        .AddEntityFrameworkStores<DataContext>()
        .AddSignInManager<SignInManager<AppUser>>()
        .AddRoleManager<RoleManager<AppRole>>();

    var Key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["TokenKey"]));

    // 修改此处:指定JWT为默认认证方案
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(opt =>
    {
        opt.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = Key,
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

    services.AddScoped<TokenService>();

    services.AddAuthorization(opt =>
    {
        opt.AddPolicy("Verified", pol => 
            pol.RequireRole("User", "Staff", "Admin", "Guest"));
        opt.AddPolicy("Restricted", pol =>
            pol.RequireRole("User", "Staff", "Admin"));
        opt.AddPolicy("EmployeeAccess", pol =>
            pol.RequireRole("Staff", "Admin"));
        opt.AddPolicy("ManagerAccess", pol =>
            pol.RequireRole("Admin"));
    });

    return services;
}

方案2:换回AddIdentityCore(纯API场景推荐)

如果你的项目是纯API服务,不需要Cookie认证,建议继续使用AddIdentityCore,手动添加角色和登录管理服务,避免Identity自动注册Cookie认证:

public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration config)
{
    // 用AddIdentityCore替代AddIdentity,避免自动注册Cookie认证
    services.AddIdentityCore<AppUser>(opt =>
    {
        opt.Password.RequireNonAlphanumeric = false;
    })
        .AddRoles<AppRole>() // 手动添加角色支持
        .AddEntityFrameworkStores<DataContext>()
        .AddSignInManager<SignInManager<AppUser>>()
        .AddRoleManager<RoleManager<AppRole>>();

    var Key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["TokenKey"]));

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(opt =>
        {
            opt.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = Key,
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });

    services.AddScoped<TokenService>();

    services.AddAuthorization(opt =>
    {
        opt.AddPolicy("Verified", pol => 
            pol.RequireRole("User", "Staff", "Admin", "Guest"));
        opt.AddPolicy("Restricted", pol =>
            pol.RequireRole("User", "Staff", "Admin"));
        opt.AddPolicy("EmployeeAccess", pol =>
            pol.RequireRole("Staff", "Admin"));
        opt.AddPolicy("ManagerAccess", pol =>
            pol.RequireRole("Admin"));
    });

    return services;
}

额外检查项

  1. 确保Program.cs中的中间件顺序正确:
app.UseAuthentication(); // 认证必须在授权之前执行
app.UseAuthorization();
  1. 验证JWT令牌内容:将生成的令牌复制到本地解码工具(如jwt.io,仅本地解析无需上传),确认payload中包含email、name、nameid等预期Claims。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:52:11