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

ASP.NET Web API中JWT认证返回401错误的排查求助

ASP.NET Web API JWT认证始终返回401未授权错误

在ASP.NET Web API接口添加[Authorize]特性后,使用JWT令牌进行身份认证时,始终收到401未授权错误。

我的项目配置

using FluentValidation;
using FluentValidation.AspNetCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using Server.Api.Extensions;
using Server.Api.Middlewares;
using Server.Domain.Interfaces;
using Server.Domain.Services;
using Server.Infrastructure;

var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("AveAnticaDbContextConnection") ?? throw new InvalidOperationException("Connection string 'AzureDbConnection' not found.");
ConfigurationManager configuration = builder.Configuration;

builder.Services.AddDbContext<AveAnticaDbContext>(x => x.UseSqlServer(connectionString));

builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

builder.Services.AddControllers();


builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddValidatorsFromAssemblies(AppDomain.CurrentDomain.GetAssemblies());


builder.Services.AddScoped<IProductService, ProductService>();
builder.Services.AddScoped<IImageService, ImageService>();
builder.Services.AddScoped<ICategoryService, CategoryService>();
builder.Services.AddScoped<ILanguageService, LanguageService>();
builder.Services.AddScoped<ITagService, TagService>();
builder.Services.AddScoped<ILikesService, LikesService>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IAccountService, AccountService>();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

builder.Services.AddAuthentication();
builder.Services.ConfigureIdentity();
builder.Services.ConfigureJWT(builder.Configuration);

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();

builder.Services.ConfigureSwagger();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseCors(options =>
{
    options.AllowAnyHeader();
    options.AllowAnyMethod();
    options.AllowAnyOrigin();
});

app.UseMiddleware<JwtTokenMiddleware>();
app.UseMiddleware<ExceptionMiddleware>();

app.UseHttpsRedirection();

//app.UseResponseCaching();

app.UseAuthentication();
app.UseAuthorization();

var directPath = "Uploads";//builder.Configuration.GetConnectionString("Path");
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
           Path.Combine(builder.Environment.ContentRootPath, directPath)),
    RequestPath = "/" + directPath
});

app.MapControllers();

app.Run();

配置扩展类

public static class ServiceExtension
{
    public static void ConfigureIdentity(this IServiceCollection services)
    {
        var builder = services.AddIdentity<Customer, IdentityRole>(o =>
        {
            o.Password.RequireDigit = false;
            o.Password.RequireLowercase = false;
            o.Password.RequireUppercase = false;
            o.Password.RequireNonAlphanumeric = false;
            o.User.RequireUniqueEmail = true;
        })
        .AddEntityFrameworkStores<AveAnticaDbContext>()
        .AddDefaultTokenProviders();
    }

    public static void ConfigureJWT(this IServiceCollection services, IConfiguration configuration)
    {
        var jwtConfig = configuration.GetSection("JwtOptions");
        var secretKey = jwtConfig["Key"];
        services.AddAuthentication(opt =>
        {
            opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateLifetime = true,
                ValidateAudience = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = jwtConfig["Issuer"],
                ValidAudience = jwtConfig["Audience"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey))
            };
        });
    }
    public static void ConfigureSwagger(this IServiceCollection services)
    {
        services.AddSwaggerGen(option =>
        {
            option.SwaggerDoc("v1", new OpenApiInfo { Title = "Demo API", Version = "v1" });
            option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                In = ParameterLocation.Header,
                Description = "Please enter a valid token",
                Name = "Authorization",
                Type = SecuritySchemeType.Http,
                BearerFormat = "JWT",
                Scheme = "Bearer"
            });
            option.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type=ReferenceType.SecurityScheme,
                            Id="Bearer"
                        }
                    },
                    new string[]{}
                }
            });
        });
    }
}

账户服务(令牌生成相关代码)

public async Task<string> CreateTokenAsync(Customer user)
{
    var signingCredentials = GetSigningCredentials();
    var claims = await GetClaims(user);
    var tokenOptions = GenerateTokenOptions(signingCredentials, claims);
    return new JwtSecurityTokenHandler().WriteToken(tokenOptions);
}

private SigningCredentials GetSigningCredentials()
{
    var jwtConfig = configuration.GetSection("JwtOptions");
    var key = Encoding.UTF8.GetBytes(jwtConfig["Key"]);
    var secret = new SymmetricSecurityKey(key);
    return new SigningCredentials(secret, SecurityAlgorithms.HmacSha256);
}

private async Task<List<Claim>> GetClaims(Customer user)
{
    var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, user.UserName)
        };
    var roles = await userManager.GetRolesAsync(user);
    foreach (var role in roles)
    {
        claims.Add(new Claim(ClaimTypes.Role, role));
    }
    return claims;
}

JWT配置(appsettings.json)

"JwtOptions": {
  "Issuer": "AveAntica",
  "Lifetime": 12,
  "Audience": "AveAnticaAudience",
  "Key": "1234234rearaeta4wa4rras4tra"
},

已尝试的排查步骤

  • 同时使用[Authorize]和[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]特性,问题依旧
  • 确认请求中已正确传递JWT令牌,且解码后内容正常
  • 对比运行正常的同类项目配置,调整自身配置无效
  • 更新所有相关NuGet包,问题仍未解决

需要协助排查此JWT认证401错误的原因。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:49:55