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; }
额外检查项
- 确保
Program.cs中的中间件顺序正确:
app.UseAuthentication(); // 认证必须在授权之前执行 app.UseAuthorization();
- 验证JWT令牌内容:将生成的令牌复制到本地解码工具(如jwt.io,仅本地解析无需上传),确认
payload中包含email、name、nameid等预期Claims。
内容的提问来源于stack exchange,提问作者Steven Beltran
相关产品推荐
相关产品推荐

