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

ASP.NET中JWT认证接口始终返回401未授权问题求助

问题分析与解决方案

你的核心问题是:默认JwtBearer认证中间件只会从Authorization: Bearer <token>请求头读取令牌,但你把JWT存在了HttpOnly Cookie中,导致认证逻辑找不到令牌,返回401未授权。以下是具体修复步骤:


1. 修改JwtBearer配置,支持从Cookie读取令牌

在Program.cs的AddJwtBearer配置中,添加事件逻辑,让中间件从指定Cookie中提取令牌:

builder.Services.AddAuthentication(options => {
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("very-safe-secret")),
        // 你当前的令牌未配置Issuer和Audience,需关闭这两项验证,否则会触发认证失败
        ValidateIssuer = false,
        ValidateAudience = false,
        AuthenticationType = "Bearer"
    };
    // 添加从Cookie读取令牌的逻辑
    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            // 这里的"jwt"要和你存入Cookie时的名称完全一致
            context.Token = context.Request.Cookies["jwt"];
            return Task.CompletedTask;
        }
    };
});

2. 优化JWT生成逻辑(可选但推荐)

你的JWTokenHandler未设置令牌过期时间,建议添加避免令牌永久有效:

public JWTokenHandler(string payload) {
    _tokenHandler = new JwtSecurityTokenHandler();
    _key = Encoding.ASCII.GetBytes("very-safe-secret");
    _tokenDescriptor = new SecurityTokenDescriptor {
        Subject = new ClaimsIdentity(new[] {
            new Claim("payload", payload)
        }),
        // 设置令牌1小时后过期
        Expires = DateTime.UtcNow.AddHours(1),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(_key), SecurityAlgorithms.HmacSha256Signature)
    };
}

3. 正确存入HttpOnly Cookie的示例

在你的登录接口中,生成令牌后按以下方式存入Cookie:

[HttpPost("login")]
public IActionResult Login(string username, string password)
{
    // 这里替换为你的用户验证逻辑
    bool isValidUser = true;
    if (!isValidUser) return Unauthorized();

    var tokenHandler = new JWTokenHandler("user-payload-data");
    var token = tokenHandler.generateToken();
    
    // 存入HttpOnly Cookie
    Response.Cookies.Append("jwt", token, new CookieOptions
    {
        HttpOnly = true,
        Secure = !builder.Environment.IsDevelopment(), // 生产环境强制HTTPS
        SameSite = SameSiteMode.Strict,
        Expires = DateTime.UtcNow.AddHours(1) // 与令牌过期时间保持一致
    });
    
    return Ok("登录成功");
}

4. Postman测试步骤

  1. 调用登录接口,Postman会自动保存返回的HttpOnly Cookie
  2. 直接调用api/Character的Get接口,无需手动添加Authorization头,认证中间件会自动从Cookie读取令牌完成授权

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:44:54