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

所有控制器中HttpContext.User始终为null的技术求助

问题描述

在任意控制器中执行var usr = User as ClaimsPrincipal;,结果始终为null。已完成的应用配置如下:

var builder = WebApplication.CreateBuilder(args);

ConfigurationManager configuration = builder.Configuration;
builder.Services.AddDbContext<CustomIdentityDbContext>(options =>
{
    options.UseSqlServer(configuration.GetConnectionString("SqlServerConnection")).EnableSensitiveDataLogging();

   }
);

//配置自定义身份验证
builder.Services.AddIdentity<WSA_UTENTE, WSA_RUOLI>(options =>
{
    options.SignIn.RequireConfirmedAccount = true;
})
.AddEntityFrameworkStores<CustomIdentityDbContext>()
.AddDefaultTokenProviders();


//添加JWT认证中间件
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
});

能够成功生成Token,生成方法如下:

private JwtSecurityToken GetToken(IEnumerable<Claim> authClaims)
{
    var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));

    var token = new JwtSecurityToken(
        issuer: _configuration["Jwt:ValidIssuer"],
        audience: _configuration["Jwt:ValidAudience"],
        expires: DateTime.Now.AddMinutes(String.IsNullOrEmpty(_configuration["Jwt:AccessTokenLifetime"]) ? int.Parse(_configuration["Jwt:AccessTokenLifetime"]) : 525600),
        claims: authClaims,
        signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
        );

    return token;
}

Token包含的主要Claims:

"sub: 8001ac54-12c0-4d18-f5a7-08db0445001d"
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: myusername"

疑问:是否需要调用HttpContext.SignInAsync来填充HttpContext.User,还是JWT中间件会自动完成该操作?


问题分析与解决

核心结论

JWT认证中间件会自动解析请求头中的有效Token并填充HttpContext.User,不需要调用HttpContext.SignInAsync(该方法是Cookie认证流程的环节,和JWT无关)。你的问题大概率出在以下几个环节:

排查点1:中间件顺序错误

必须保证中间件的执行顺序正确:

var app = builder.Build();

// 其他中间件(如静态文件)
app.UseStaticFiles();

app.UseRouting();

// 必须在UseRouting之后、UseAuthorization之前添加
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

如果UseAuthentication()顺序不对,认证逻辑不会触发,User会保持null。

排查点2:请求未携带有效Token

调用接口时,必须在请求头中添加Authorization字段,格式为:

Authorization: Bearer <你的JWT Token字符串>

没有携带该头的话,JWT中间件不会执行解析逻辑。

排查点3:Token配置不匹配

检查生成Token和验证Token的配置项是否一致:

  • 生成Token用的是_configuration["Jwt:ValidIssuer"]和_configuration["Jwt:ValidAudience"]
  • 验证时用的是builder.Configuration["Jwt:Issuer"]和builder.Configuration["Jwt:Audience"]
    如果配置文件中这两组键名不一致,会导致Token验证失败,User无法被填充。

排查点4:控制器未添加授权特性

确保目标控制器或Action上添加了[Authorize]特性:

[Authorize]
public class YourController : ControllerBase
{
    // ...
}

没有该特性的话,认证逻辑不会被触发,User会保持默认空状态。

调试验证

可以在请求管道中添加调试代码,确认认证状态:

app.Use(async (context, next) =>
{
    Console.WriteLine($"用户是否已认证:{context.User.Identity.IsAuthenticated}");
    await next();
});

将这段代码放在UseAuthentication()之后,运行程序调用接口,查看控制台输出,判断认证是否生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:50:15