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

ASP.NET Core 3.1 MVC JWT生成正常但请求始终返回401错误求助

问题根因及修复方案

1. 认证配置重复覆盖错误

ConfigureServices方法中两次调用了AddAuthentication方法,后注册的Cookie认证会覆盖之前的JWT认证默认配置,导致全局默认认证方案变为Cookie,携带JWT的请求自然无法通过认证。

2. 中间件执行顺序错误

Configure方法中认证和授权中间件顺序颠倒:必须先执行UseAuthentication完成身份校验,再执行UseAuthorization完成权限校验,顺序错误会导致授权逻辑拿不到认证信息直接返回401。

3. 多认证方案兼容问题

如果确实需要同时支持JWT和Cookie两种认证方式,不能重复调用AddAuthentication,需要合并配置。


具体修复代码

修改ConfigureServices方法

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors();
    services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
    services.AddControllersWithViews();
    services.AddRazorPages();
    var tokenOptions = Configuration.GetSection("TokenOptions").Get<TokenOptions>();

    // 合并认证配置,不要重复调用AddAuthentication
    services.AddAuthentication(options =>
        {
            // 可根据业务设置默认方案,或者给接口单独指定认证方案
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidIssuer = tokenOptions.Issuer,
                ValidAudience = tokenOptions.Audience,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = SecurityKeyHelper.CreateSecurityKey(tokenOptions.SecurityKey),
                // 可选:修复时区差问题,允许一定的时间偏移
                ClockSkew = TimeSpan.FromMinutes(5)
            };
        })
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o =>
        {
            o.LoginPath = "/Auth/Login";
        });

    services.AddDependencyResolvers(new ICoreModule[] {
        new CoreModule()
    });
    // 删除重复的services.AddControllersWithViews()调用
}

修改Configure方法的中间件顺序

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseCors(builder => builder.WithOrigins("https://localhost:44378").AllowAnyHeader().AllowAnyMethod());
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

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

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Customer}/{action=Index}/{id?}");
    });
    app.UseStatusCodePages();
}

其他注意事项

  • 生成JWT时建议统一使用DateTime.UtcNow代替DateTime.Now,避免时区差异导致的token过期校验失败
  • 发起请求时Authorization头格式必须正确:Bearer 你的token值,注意Bearer和token之间有且仅有一个空格
  • 如果部分接口需要使用Cookie认证,给对应Controller/Action加上[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]特性即可
  • 如果部分接口需要使用JWT认证,给对应Controller/Action加上[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]特性即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:57:03