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

启用JWT认证后无法通过User.Identity获取用户信息的问题

问题:同时启用Cookie与JWT认证后无法获取User.Identity信息

原本项目采用Cookie认证,添加JWT认证后,无法通过User.Identity对象获取用户信息。当前Program.cs中的认证配置代码如下:

builder.Services.AddAuthentication(options => {
    options.DefaultAuthenticateScheme = "JWT_OR_COOKIE"/*"Identity.Application"*/;
    options.DefaultChallengeScheme = "JWT_OR_COOKIE";
}) 
.AddCookie("Cookies", options =>
{
    options.LoginPath = "/identity/account/login";
    options.ExpireTimeSpan = TimeSpan.FromDays(1);
})
.AddJwtBearer("Bearer",options =>
{
    options.RequireHttpsMetadata = false;
    
    options.Authority = "/Security/Token/Validate"; // TODO: Update URL
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience=builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["Jwt:Key"])),
    };
    
    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            var accessToken = context.Request.Query["access_token"];

            var path = context.HttpContext.Request.Path;
            if (!string.IsNullOrEmpty(accessToken) &&
                (path.StartsWithSegments("/ConnectionsHub")))
            {
                context.Token = accessToken;
            }
            return Task.CompletedTask;
        }
    };
})
.AddPolicyScheme("JWT_OR_COOKIE", "JWT_OR_COOKIE", options =>
{
    // runs on each request
    options.ForwardDefaultSelector = context =>
    {
        string authorization = context.Request.Headers[HeaderNames.Authorization];
        if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer "))
            return "Bearer";

        return "Cookies";
    };
});
...
app.UseAuthentication();

app.UseAuthorization();

解决方案

针对无法获取User.Identity信息的问题,可从以下方向排查修复:

1. 统一JWT与Cookie的Claim映射

JWT默认的名称Claim为name,而ASP.NET Core Identity默认使用ClaimTypes.Name(对应URI格式的Claim类型)。需在JWT配置中指定匹配的Claim类型,确保两者统一:

options.TokenValidationParameters = new TokenValidationParameters
{
    ValidIssuer = builder.Configuration["Jwt:Issuer"],
    ValidAudience=builder.Configuration["Jwt:Audience"],
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["Jwt:Key"])),
    // 添加以下配置,对齐Claim类型
    NameClaimType = ClaimTypes.Name,
    RoleClaimType = ClaimTypes.Role
};

2. 验证Cookie认证的Claim保留逻辑

如果使用ASP.NET Core Identity的Cookie认证,避免自定义Cookie配置时覆盖默认的Claim序列化/反序列化逻辑,确保用户Claims能被正确存储和读取。

3. 检查PolicyScheme转发逻辑正确性

可在ForwardDefaultSelector中添加日志,确认当前请求被转发到了正确的认证Scheme,排查是否存在请求匹配错误:

options.ForwardDefaultSelector = context =>
{
    string authorization = context.Request.Headers[HeaderNames.Authorization];
    if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer "))
    {
        // 可添加日志记录:当前使用JWT认证
        return "Bearer";
    }
    // 可添加日志记录:当前使用Cookie认证
    return "Cookies";
};

4. 确认中间件执行顺序

保证app.UseAuthentication()在app.UseAuthorization()之前执行,且位于所有需要访问用户信息的业务中间件之前。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:37:27