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

调用API端点遇Forbidden错误:API密钥验证问题排查请求

API Gateway启用API密钥后调用返回Forbidden问题排查与修复

问题现象

无API密钥时可正常调用端点:

https://xxxxxxxx6.execute-api.us-east-1.amazonaws.com/test/pets

添加API密钥配置后,通过?key=abcdef查询参数调用时返回Forbidden错误。


相关资源配置

Lambda函数配置

MyLambdaFunction:
  Type: AWS::Serverless::Function
  Properties:
    Description: >
      Currently does not support S3 upload event.
    Handler: app.lambda_handler
    Runtime: python3.12
    FunctionName:
      !Sub
        - "${TheEnv}-${TheAppNameForResources}-get-v1"
        - TheEnv: !Ref Environment
          TheAppNameForResources: !Ref AppNameForResources
    CodeUri: .
    MemorySize: 10240
    Role: !GetAtt MyLambdaExecutionRole.Arn
    Events:
      MyPetsAPIEvent:
        Type: Api
        Properties:
          RestApiId:
            Ref: MyApiGateway
          Path: /pets
          Method: GET
          RequestParameters:
            - method.request.header.Authorization:
                Required: true
                Caching: true
    Tracing: Active

API Gateway配置

MyApiGateway:
  Type: AWS::Serverless::Api
  Properties:
    Variables:
      stageName: test
    Name:
      !Sub
      - '${TheEnv}-${TheAppNameForResources}-api'
      - TheEnv: !Ref Environment
        TheAppNameForResources: !Ref AppNameForResources
        TheBucketRegion: !Ref AWS::Region
    TracingEnabled: true
    OpenApiVersion: 3.0.2
    Cors:
      AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
      AllowMethods: "'*'"
      AllowOrigin: "'*'"
    StageName: test
    Auth:
      ApiKeyRequired: true
      UsagePlan:
        CreateUsagePlan: PER_API
        UsagePlanName: "my_api_batch"
        ResourcePolicy:
        CustomStatements:
          - Effect: Allow
            Principal: "*"
            Action: "execute-api:Invoke"
            Resource: "execute-api:/test/GET/pets"

IAM角色配置

MyLambdaExecutionRole:
  Type: AWS::IAM::Role
  Properties:
    RoleName:
      !Sub
      - "${TheAppNameForResources}-${TheEnvName}-lambda-execution-role"
      - TheAppNameForResources: !Ref AppNameForResources
        TheEnvName: !Ref Environment
    AssumeRolePolicyDocument:
      Statement:
        - Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: ['sts:AssumeRole']
    Policies:
      - PolicyName:
          !Sub
          - "${TheAppNameForResources}-${TheEnvName}-lambda-execution-role-policy"
          - TheAppNameForResources: !Ref AppNameForResources
            TheEnvName: !Ref Environment
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - 'logs:CreateLogGroup'
                - 'logs:CreateLogStream'
                - 'logs:PutLogEvents'
                - 'batch:SubmitJob'
                - 'batch:DescribeJobs'
                - 'batch:CancelJob'
                - 'apiGateway:Invoke'
                - 'S3:*'
              Resource: "*"

Lambda函数代码

def lambda_handler(event, context):
  print('event ====> ', event)
  print(event['resource'])
  api_key = event['queryStringParameters']['key']
  print('api_key = ', api_key)
  route = event['resource']
  jobQueue = "dev-myjobQueue-api"
  batch_client = boto3.client('batch')

  if route == '/pets':
    response = batch_client.submit_job(
        jobDefinition='pets-job-def',
        jobName='pets-job-name',
        jobQueue=jobQueue,
    )
    return {
        'statusCode': 200,
        'body': json.dumps('AWS Batch job submitted successfully.')
    }

问题根源

  1. API密钥传递方式错误:API Gateway要求API密钥通过X-Api-Key请求头传递,而非URL查询参数key,不符合要求的传递方式会触发验证失败。
  2. Authorization头强制要求冲突:Lambda的API事件配置中强制要求Authorization头,但当前场景仅需API密钥验证,缺少该头会直接被拒绝。
  3. API密钥未关联使用计划:启用ApiKeyRequired: true后,API密钥必须关联到对应的使用计划my_api_batch,否则网关会拒绝请求。
  4. 资源Policy格式错误:Resource字段格式不符合AWS规范,正确格式应为ARN格式,而非execute-api:/test/GET/pets。

修复步骤

1. 修正API密钥传递方式

将API密钥放在X-Api-Key请求头中,示例curl请求:

curl -H "X-Api-Key: abcdef" https://xxxxxxxx6.execute-api.us-east-1.amazonaws.com/test/pets

2. 移除不必要的Authorization头要求

修改Lambda的Events配置,删除RequestParameters中的Authorization必填项:

MyLambdaFunction:
  # ... 其他配置保留
  Events:
    MyPetsAPIEvent:
      Type: Api
      Properties:
        RestApiId: !Ref MyApiGateway
        Path: /pets
        Method: GET
        # 移除以下配置
        # RequestParameters:
        #   - method.request.header.Authorization:
        #       Required: true
        #       Caching: true

3. 关联API密钥到使用计划

  • 控制台操作:在API Gateway控制台找到你的API密钥,将其关联到my_api_batch使用计划。
  • SAM模板添加资源(可选):
MyApiKey:
  Type: AWS::ApiGateway::ApiKey
  Properties:
    Name: "my-api-key"
    Enabled: true
    StageKeys:
      - RestApiId: !Ref MyApiGateway
        StageName: test

MyUsagePlanKey:
  Type: AWS::ApiGateway::UsagePlanKey
  Properties:
    KeyId: !Ref MyApiKey
    KeyType: API_KEY
    UsagePlanId: !GetAtt MyApiGateway.UsagePlan.Id

4. 修正资源Policy格式

修改API Gateway的ResourcePolicy为正确的ARN格式:

MyApiGateway:
  # ... 其他配置保留
  Auth:
    ApiKeyRequired: true
    UsagePlan:
      CreateUsagePlan: PER_API
      UsagePlanName: "my_api_batch"
      ResourcePolicy:
        CustomStatements:
          - Effect: Allow
            Principal: "*"
            Action: "execute-api:Invoke"
            Resource: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${MyApiGateway}/test/GET/pets"

5. 调整Lambda代码(可选)

如果需要在Lambda中获取API密钥,从请求头而非查询参数读取:

def lambda_handler(event, context):
  print('event ====> ', event)
  print(event['resource'])
  # 从请求头获取API密钥
  api_key = event.get('headers', {}).get('X-Api-Key')
  print('api_key = ', api_key)
  route = event['resource']
  jobQueue = "dev-myjobQueue-api"
  batch_client = boto3.client('batch')

  if route == '/pets':
    response = batch_client.submit_job(
        jobDefinition='pets-job-def',
        jobName='pets-job-name',
        jobQueue=jobQueue,
    )
    return {
        'statusCode': 200,
        'body': json.dumps('AWS Batch job submitted successfully.')
    }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:07:02