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

ASP.NET Core中x-api-key认证返回401的问题排查

问题诊断与修复方案

你的代码存在几个关键问题,导致API密钥获取为空且返回401,以下是具体修复步骤:

1. 修复ApiKeyAuthorizationAttribute的依赖注入问题

特性(Attribute)无法通过构造函数直接注入服务,你当前的_configuration字段始终为null,导致验证逻辑完全失效。需要从HttpContext的服务容器中获取IConfiguration:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class ApiKeyAuthorizationAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        // 从请求服务容器中获取IConfiguration实例
        var configuration = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
        var apiKey = context.HttpContext.Request.Headers["x-api-key"].FirstOrDefault();

        if (string.IsNullOrEmpty(apiKey) || !IsApiKeyValid(apiKey, configuration))
        {
            context.Result = new UnauthorizedResult();
        }
    }

    private bool IsApiKeyValid(string apiKey, IConfiguration configuration)
    {
        var allowedApiKeys = configuration.GetSection("AllowedApiKeys").Get<string[]>();
        // 处理配置为空的边界情况,避免空引用异常
        return allowedApiKeys?.Contains(apiKey) ?? false;
    }
}

2. 修复ApiKeyMiddleware的配置读取逻辑

你当前直接通过_configuration["AllowedApiKeys"]读取配置,如果AllowedApiKeys是数组格式,这个方法会返回null,导致验证条件永远不成立。需要改为读取数组配置:

public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IConfiguration _configuration;

    public ApiKeyMiddleware(RequestDelegate next, IConfiguration configuration)
    {
        _next = next;
        _configuration = configuration;
    }

    public async Task Invoke(HttpContext context)
    {
        var apiKey = context.Request.Headers["x-api-key"].FirstOrDefault();
        var allowedApiKeys = _configuration.GetSection("AllowedApiKeys").Get<string[]>();

        // 验证API密钥非空且在允许列表中
        if (!string.IsNullOrEmpty(apiKey) && allowedApiKeys?.Contains(apiKey) == true)
        {
            await _next(context);
        }
        else
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            await context.Response.WriteAsync("Unauthorized");
        }
    }
}

3. 确认配置文件格式

确保appsettings.json中的AllowedApiKeys配置为数组格式(推荐使用):

{
  "AllowedApiKeys": ["YourValidKey1", "YourValidKey2"]
}

如果使用逗号分隔的字符串格式,需要修改配置读取逻辑:

// 在中间件或特性中替换为以下代码
var allowedApiKeys = _configuration["AllowedApiKeys"]?.Split(',', StringSplitOptions.RemoveEmptyEntries);

4. 避免重复验证逻辑

你同时实现了中间件和特性两种验证方式,建议二选一:

  • 若需全局所有API强制验证:在Program.cs中注册中间件,无需添加[ApiKeyAuthorization]特性
    app.UseMiddleware<ApiKeyMiddleware>();
    
  • 若需部分API验证:仅使用[ApiKeyAuthorization]特性,无需注册中间件

5. 调试建议

在验证逻辑中添加日志输出,确认API密钥和配置是否正确读取:

// 在中间件的Invoke方法中添加
var logger = context.RequestServices.GetRequiredService<ILogger<ApiKeyMiddleware>>();
logger.LogInformation("Received API Key: {ApiKey}", apiKey);
logger.LogInformation("Allowed API Keys: {AllowedKeys}", allowedApiKeys != null ? string.Join(",", allowedApiKeys) : "None");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:05:00