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

.NET Core JWT认证中User.Identity未认证且Claims为空的问题

.NET Core JWT认证问题排查与解决

核心问题根源

出现User.Identity.IsAuthenticated=false、Claims为空且[Authorize]返回401,是由以下配置/编码错误导致:


1. 缺失认证授权中间件或顺序错误

Program.cs中仅注册了认证服务,但未添加认证、授权中间件,且中间件顺序必须严格遵循先认证后授权,并放在UseRouting之后、UseEndpoints之前。

修复代码:

// 保留你原有的认证服务注册代码
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            //ValidateIssuer = true,
            //ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
        };
    });

// 必须添加这两行,注意顺序!
app.UseAuthentication(); // 先执行认证逻辑
app.UseAuthorization();  // 再执行授权逻辑

// 后续配置端点
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

2. 密钥编码不一致

生成Token时使用Encoding.ASCII,但验证时使用Encoding.UTF8,若密钥包含ASCII范围外字符,会直接导致签名验证失败,认证被拒绝。

修复GenerateJwtToken方法:

private string GenerateJwtToken(CurrentUserVM currentUser)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    // 统一使用UTF8编码,与验证端保持一致
    var key = Encoding.UTF8.GetBytes(_config.GetSection("Jwt:Key").Value); 
    var ExpireMinutes = _config.GetSection("Jwt:ExpireMinutes").Value;
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new Claim[]
        {
            new Claim(ClaimTypes.NameIdentifier, currentUser.UserId.ToString()),
            new Claim(ClaimTypes.GroupSid, currentUser.OrgId.ToString()),
            new Claim(ClaimTypes.Role, currentUser.RoleCode)
        }),
        Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(ExpireMinutes)),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
            SecurityAlgorithms.HmacSha512Signature)
    };
    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}

3. 角色授权的额外适配(针对[Authorize(Roles="Admin")])

若前两步修复后仍出现403/401,需确保JWTBearer正确识别角色声明:

  • 方式一:在AddJwtBearer配置中显式指定角色声明类型
options.TokenValidationParameters.RoleClaimType = ClaimTypes.Role;
  • 方式二:生成Token时使用JWT标准角色声明字段
new Claim(JwtRegisteredClaimNames.Role, currentUser.RoleCode)

调试辅助建议

  • 用jwt.io解析生成的Token,检查Claims是否正确、签名是否有效
  • 开启认证失败日志,定位具体错误原因:
options.Events = new JwtBearerEvents
{
    OnAuthenticationFailed = context =>
    {
        Console.WriteLine($"认证失败详情: {context.Exception.Message}");
        return Task.CompletedTask;
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 09:25:28