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

ASP.NET Core 7 MVC中JWT认证遇401错误求助

问题分析与解决方案

核心问题

你遇到的401错误主要来自三个关键点:

  1. 中间件顺序错误:认证、授权中间件的调用顺序不符合ASP.NET Core规范,且缺少路由中间件
  2. JWT获取逻辑缺失:默认JwtBearer中间件只会读取Authorization: Bearer <token>请求头,无法识别你存在Cookie中的Token
  3. MVC场景下的方案适配问题:手动将JWT存Cookie并非MVC项目的最优实践,框架内置的Cookie认证更适配服务器端渲染场景

解决方案一:调整JwtBearer配置读取Cookie

如果你坚持使用JWT方案,需要修改配置让中间件从Cookie中获取Token,并修正中间件顺序:

1. 修改Program.cs中的JwtBearer配置

builder.Services
    .AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            ValidateAudience = false,
            ValidateIssuer = false,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetSection("AppSettings:JwtSecret").Value!))
        };

        // 添加从Cookie读取Token的逻辑
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                context.Token = context.Request.Cookies["TokenCookie"];
                return Task.CompletedTask;
            }
        };
    });

2. 修正Program.cs的中间件顺序

中间件必须严格遵循以下顺序:

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

// 新增路由中间件,MVC必须依赖该中间件
app.UseRouting();

// 先认证,再授权,顺序不能颠倒
app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Login}/{action=Index}/{id?}");

app.Run();

3. 优化Cookie的安全属性

存储Token时添加安全配置,防止XSS和CSRF攻击:

// 在Authenticate方法中修改Cookie写入逻辑
Response.Cookies.Append("TokenCookie", token, new CookieOptions
{
    HttpOnly = true, // 禁止JS读取Cookie
    Secure = app.Environment.IsProduction(), // 生产环境仅HTTPS传输
    SameSite = SameSiteMode.Strict, // 限制跨站请求携带Cookie
    Expires = DateTime.Now.AddMinutes(60)
});

解决方案二:改用ASP.NET Core内置Cookie认证(推荐MVC场景)

MVC是服务器端渲染项目,使用框架内置的Cookie认证更省心,无需手动处理JWT的生成与存储:

1. 修改Program.cs的认证配置

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Login/Index"; // 未认证时自动跳转登录页
        options.ExpireTimeSpan = TimeSpan.FromMinutes(60); // Cookie有效期
        options.Cookie.Name = "AuthCookie"; // 自定义Cookie名称
        options.Cookie.HttpOnly = true;
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 生产环境强制HTTPS
        options.Cookie.SameSite = SameSiteMode.Strict;
    });

2. 修改Authenticate登录方法

[HttpPost]
public async Task<IActionResult> Authenticate(string user, string passwd)
{
    if (someLogic)
    {
        // 创建用户身份声明
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, user)
        };
        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        var principal = new ClaimsPrincipal(identity);

        // 生成认证Cookie
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties
        {
            ExpiresUtc = DateTime.UtcNow.AddMinutes(60)
        });

        return RedirectToAction("Index", "Home");
    }
    else
    {
        TempData["ErrorLogin"] = "Invalid credentials";
        return RedirectToAction("Index", "Login");
    }
}

3. 中间件顺序同方案一

确保UseRouting→UseAuthentication→UseAuthorization的顺序正确。


额外检查项

  • 确认appsettings.json中AppSettings:JwtSecret存在,且长度不少于16字节(HmacSha256算法要求)
  • 受保护的控制器/Action需添加[Authorize]属性:
    [Authorize]
    public class HomeController : Controller
    {
        public IActionResult Index() => View();
    }
    

内容的提问来源于stack exchange,提问作者ram.rs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:02:16