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

.NET 7 Identity JwtBearer:[Authorize]特性未生效问题求助

问题排查与修复步骤

1. 修正中间件顺序(核心问题)

Program.cs中中间件执行顺序错误,UseAuthentication必须在UseAuthorization之前,且UseCors需放在认证逻辑之前。修改后的Pipeline配置如下:

var app = builder.Build();

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

app.UseHttpsRedirection();
// 先启用跨域策略
app.UseCors("CORSPolicy");
// 启用身份认证(必须在授权之前执行)
app.UseAuthentication();
// 启用授权验证
app.UseAuthorization();

app.MapControllerRoute(
    name: "Topic",
    pattern: "topic/*{action}"
);

app.Run();

2. 配置JWT Bearer认证规则

当前AddJwtBearer()未指定任何验证参数,框架无法识别自定义生成的JWT。需补充与token生成逻辑匹配的验证配置:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            // 验证签名密钥有效性
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                builder.Configuration.GetSection("AppSettings:Token").Value!)),
            // 验证token发行方(需与生成token时一致)
            ValidateIssuer = true,
            ValidIssuer = "SdeResearchApi",
            // 验证token受众(需与生成token时一致)
            ValidateAudience = true,
            ValidAudience = "SdeResearchApiUsers",
            // 验证token有效期
            ValidateLifetime = true,
            // 关闭时钟偏差容忍(避免过期token被误判)
            ClockSkew = TimeSpan.Zero
        };
    });

3. 修复JWT生成逻辑

当前CreateToken直接修改token.Payload不符合规范,且未指定Issuer和Audience,导致验证失败。改用Claims参数添加自定义声明,并补充发行方/受众信息:

private async Task<string> CreateToken(ApplicationUser user)
{
    var roles = await _userManager.GetRolesAsync(user);
    
    // 构建标准JWT声明
    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, user.Id),
        new Claim(ClaimTypes.Name, user.UserName!)
    };
    
    // 添加角色声明
    foreach (var role in roles)
    {
        claims.Add(new Claim(ClaimTypes.Role, role));
    }

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
        _configuration.GetSection("AppSettings:Token").Value!));
    
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

    var token = new JwtSecurityToken(
        issuer: "SdeResearchApi", // 与认证配置中的ValidIssuer一致
        audience: "SdeResearchApiUsers", // 与认证配置中的ValidAudience一致
        claims: claims,
        expires: DateTime.Now.AddDays(1),
        signingCredentials: creds
    );

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

4. 清理冲突配置

删除appsettings.development.json中自动生成的Authentication节点,该配置属于dotnet-user-jwts工具,与自定义JWT逻辑冲突:

// 删除以下内容
"Authentication": {
    "Schemes": {
        "Bearer": {
            "ValidAudiences": [
                "http://localhost:46355",
                "https://localhost:44326",
                "https://localhost:7174",
                "http://localhost:5132"
            ],
            "ValidIssuer": "dotnet-user-jwts"
        }
    }
}

5. 验证效果

完成修改后:

  • 未携带Token访问/topic/get-all-topics时,将返回401 Unauthorized
  • 携带正确生成的Token访问时,可正常获取数据
新手核心知识点
  • 中间件顺序:ASP.NET Core中间件按注册顺序执行,认证必须在授权之前,否则授权逻辑无法获取用户认证信息
  • JWT验证三要素:Issuer(发行方)、Audience(受众)、SigningKey(签名密钥),生成和验证时必须完全一致
  • Claims规范:通过JwtSecurityToken的claims参数添加声明,而非直接修改Payload,确保符合JWT标准规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:50:44