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

在Amazon API Gateway中通过自定义授权器在URL传API Key遇权限问题

问题分析

你的核心问题是:自定义Lambda授权器执行成功,但API Gateway在使用计划验证阶段无法获取到API Key值,导致"Forbidden"错误。这是因为默认情况下,API Gateway不会自动将自定义授权器返回的usageIdentifierKey关联到API Key验证流程,需要手动补充验证逻辑或调整网关配置。

解决方法1:修改Lambda授权器,手动验证API Key与使用计划关联

步骤1:给Lambda执行角色添加权限

在IAM控制台中,为Lambda执行角色添加以下权限策略,允许查询API Key和使用计划的关联关系:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:GetApiKey",
                "apigateway:GetUsagePlanKey"
            ],
            "Resource": [
                "arn:aws:apigateway:us-east-1::/apikeys/*",
                "arn:aws:apigateway:us-east-1::/usageplans/*/keys/*"
            ]
        }
    ]
}

步骤2:更新Lambda授权器代码

替换原有代码,加入API Key与使用计划的验证逻辑:

import { APIGatewayClient, GetApiKeyCommand, GetUsagePlanKeyCommand } from "@aws-sdk/client-apigateway";

const client = new APIGatewayClient({ region: "us-east-1" });
const TARGET_USAGE_PLAN_ID = "你的使用计划ID"; // 从AWS控制台获取使用计划ID
const API_RESOURCE_ARN = "arn:aws:execute-api:us-east-1:xxxxxx:yyyyy/*/*/*/*"; // 保持原ARN

export const handler = async (event) => {
    // 从查询参数中获取API Key
    const apiKey = event.queryStringParameters?.["x-api-key"];
    if (!apiKey) {
        return generateDenyPolicy("anonymous");
    }

    try {
        // 查询API Key详情
        const apiKeyCmd = new GetApiKeyCommand({ apiKey, includeValue: false });
        const apiKeyData = await client.send(apiKeyCmd);

        // 验证API Key是否关联目标使用计划
        const usagePlanKeyCmd = new GetUsagePlanKeyCommand({
            usagePlanId: TARGET_USAGE_PLAN_ID,
            keyId: apiKeyData.id
        });
        await client.send(usagePlanKeyCmd);

        // 验证通过,返回允许策略
        return {
            principalId: apiKey,
            usageIdentifierKey: apiKey,
            policyDocument: generateAllowPolicy()
        };
    } catch (err) {
        // 验证失败,返回拒绝策略
        return generateDenyPolicy("invalid-api-key");
    }
};

// 生成允许策略的辅助函数
const generateAllowPolicy = () => ({
    Version: "2012-10-17",
    Statement: [{
        Action: "execute-api:Invoke",
        Effect: "Allow",
        Resource: API_RESOURCE_ARN
    }]
});

// 生成拒绝策略的辅助函数
const generateDenyPolicy = (principalId) => ({
    principalId,
    policyDocument: {
        Version: "2012-10-17",
        Statement: [{
            Action: "execute-api:Invoke",
            Effect: "Deny",
            Resource: API_RESOURCE_ARN
        }]
    }
});

步骤3:重新部署并测试

  1. 重新部署Lambda函数,更新API Gateway的授权器配置,确保身份源设置为querystring.x-api-key(注意格式,不是直接写x-api-key)。
  2. 使用curl测试:
    curl "https://你的API ID.execute-api.us-east-1.amazonaws.com/你的阶段/路径?x-api-key=你的API Key值"
    

解决方法2:通过集成请求映射,直接将查询参数转为头部(无需自定义授权器)

如果不需要自定义授权器的额外逻辑,仅需支持URL传API Key,可直接通过网关配置实现:

  1. 进入API Gateway控制台,选择目标API的对应资源,打开集成请求设置。
  2. 在HTTP头部区域,点击添加头部,输入x-api-key。
  3. 映射来自选择查询字符串,输入x-api-key。
  4. 重新部署API到目标阶段,确保阶段已开启API Key Required,且API Key已关联使用计划。
  5. 此时网关会自动将URL中的x-api-key参数映射为请求头部,复用原有API Key验证逻辑。

关键排查点

  • 确认阶段设置中API Key Required已开启,且API Key与使用计划关联正确。
  • 检查CloudWatch日志中Lambda的event对象,确认queryStringParameters["x-api-key"]已正确获取到值。
  • 验证Lambda执行角色的权限是否覆盖了API Key和使用计划的查询操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:53:30