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

.NET Core 6中JWT验证通过但Postman调用授权接口返回401求助

.NET Core 6 JWT认证401未授权问题排查与修复

问题情景

使用.NET Core 6创建的API项目,添加[Authorize]特性实现JWT权限控制后,jwt.io验证Token签名通过,但Postman调用受保护接口始终返回401未授权。


相关代码实现

API端点代码

[Authorize]
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
  if (_context.Users == null)
  {
      return NotFound();
  }
    return await _context.Users.ToListAsync();
}

Program.cs配置代码

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.RequireHttpsMetadata = false;
    options.SaveToken = true;    
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidateAudience = true,
        ValidAudience = builder.Configuration["Jwt:Audience"],
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
            builder.Configuration["Jwt:Key"]))
    };
});

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();

// 配置HTTP请求管道
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseCors();

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

app.Run();

Token生成方法代码

private string GetToken()
{
    var claims = new[]
    {
        new Claim(JwtRegisteredClaimNames.Sub, _configuration["Jwt:Subject"]),                
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
        new Claim(JwtRegisteredClaimNames.Iat, "1516239022"),
        new Claim("userId" , "1"),
        new Claim("name", "Jason"),
        new Claim("userName", "Jason"),
        new Claim("email", "jason@gmail.com")
    };

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("lectureTest12345"));
    var singIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
    var token = new JwtSecurityToken(
            _configuration["Jwt: Issuer"],
            _configuration["Jwt:Audience"],
            claims,
            expires: DateTime.UtcNow.AddHours(1),
            signingCredentials: singIn
            );

    return new JwtSecurityTokenHandler().WriteToken(token);
}

问题排查与修复方案

1. 修复Issuer配置键的空格问题

Token生成代码中,Issuer的配置键_configuration["Jwt: Issuer"]多了一个空格,导致读取的Issuer值与Program.cs中验证用的Jwt:Issuer不匹配,直接引发验证失败。

修复后代码:

var token = new JwtSecurityToken(
        _configuration["Jwt:Issuer"], // 去掉键名中的空格
        _configuration["Jwt:Audience"],
        claims,
        expires: DateTime.UtcNow.AddHours(1),
        signingCredentials: singIn
        );

2. 统一签名密钥配置

当前生成Token时硬编码了密钥"lectureTest12345",但Program.cs中使用的是配置文件里的Jwt:Key值,两者必须完全一致才能通过签名验证。

推荐方案:

  • 在appsettings.json中配置Jwt:Key为"lectureTest12345"
  • 或修改Token生成代码,读取配置项而非硬编码:
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));

3. 修正Iat声明的硬编码值

JwtRegisteredClaimNames.Iat被硬编码为固定字符串"1516239022",虽然默认Token验证不强制校验Iat的合理性,但建议改为当前时间的Unix时间戳,避免潜在的验证逻辑冲突:

修复后代码:

new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()),

4. 确认Postman请求头格式

确保Postman中请求头的Authorization格式正确:

  • 选择Bearer Token类型,填入生成的完整Token
  • 或手动添加请求头:Authorization: Bearer <你的Token字符串>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:55:39