【问题标题】:AWS API Gateway with Lambda Authorizer带有 Lambda 授权方的 AWS API 网关
【发布时间】:2020-02-24 02:40:00
【问题描述】:

我正在尝试配置一个 API 网关,它从请求路径中获取代理参数,以及来自 Lambda 授权方返回的参数并将其放在标头中,以便可以将其传递给我正在运行的 Elastic Beanstalk REST API弹簧靴。

代理路径按预期工作;我看到我的 Lambda 函数根据文档在“上下文”映射中返回变量“x-api-auth”。

唯一不起作用的部分是将“x-api-auth”添加到请求标头中。 :( 每当我运行我的 Jenkins 构建以更新 Cloudformation 堆栈时,我都会收到此错误:

Errors found during import: Unable to put integration on 'ANY' for resource at path '/sfdc/v1/feature-api/{proxy+}': Invalid mapping expression specified: Validation Result: warnings : [], errors : [Invalid mapping expression specified: $context.authorizer.x-api-auth] (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException

这非常令人沮丧,我仔细检查了 OpenAPI 文档以确保我的语法正确。任何帮助或提示将不胜感激!

这是我拥有的 Cloudformation 模板:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Data API pipeline initial Cloudformation template

Mappings:
  EnvironmentMapping:
    alpha:
      certificationArn: ""
      carfaxIpWhitelistRuleId: ""
      hostedZoneId: XYZ
      authLambda: ""
      sfdcAuthLambda: ""
      myApiNetworkLoadBalancer: ""
      sfdcAuthTimeout: 1
    beta:
      certificationArn: ""
      carfaxIpWhitelistRuleId: ""
      hostedZoneId: XYZ
      authLambda: ""
      sfdcAuthLambda: ""
      myApiNetworkLoadBalancer: ""
      sfdcAuthTimeout: 1
    prod:
      certificationArn: ""
      carfaxIpWhitelistRuleId: ""
      hostedZoneId: ABC
      authLambda: ""
      sfdcAuthLambda: ""
      myApiNetworkLoadBalancer: ""
      sfdcAuthTimeout: 1
Parameters:
  EnvironmentType:
    Type: "String"
    AllowedValues:
      - alpha
      - beta
      - prod

Conditions:
  UseProdCondition: !Equals [!Ref EnvironmentType, prod]

Resources:
  MyApiVpcLink:
    Type: AWS::ApiGateway::VpcLink
    Properties:
      Name: MyApiVpcLink
      Description: Allows data-api-gateway to access the VPC that my-api is on.
      TargetArns:
        - !FindInMap [EnvironmentMapping, !Ref EnvironmentType, myApiNetworkLoadBalancer]

  DataApi:
    DependsOn:
      - MyApiVpcLink
    Type: AWS::Serverless::Api
    Properties:
      Name: !Sub "${EnvironmentType}-data-api"
      StageName: !Ref EnvironmentType
      DefinitionBody:
        swagger: 2.0
        security:
          - ApiKey: []
        info:
          title: !Sub "${EnvironmentType}-data-api"
        paths:
          /sfdc/v1/my-api/{proxy+}:
            x-amazon-apigateway-any-method:
              produces:
                - application/json
              parameters:
                - in: path
                  name: proxy
                  required: true
                  schema:
                    type: string
                - in: header
                  name: x-api-auth
                  required: true
                  schema:
                    type: string
              security:
                - SfdcAuthorizer: []
                  ApiKey: []
              x-amazon-apigateway-api-key-source: HEADER
              x-amazon-apigateway-gateway-responses:
                ACCESS_DENIED:
                  statusCode: 403
                  responseTemplates:
                    application/json: '{\n\"message\": \"Access Denied\"}'
              x-amazon-apigateway-integration:
                httpMethod: ANY
                type: http_proxy
                connectionType: VPC_LINK
                connectionId: !Ref MyApiVpcLink
                passthroughBehavior: when_no_match
                uri: !If [UseProdCondition, 'http://myapp.production.aws-int.myorg.io/{proxy}',!Sub 'http://${EnvironmentType}-myapp.staging.aws-int.myorg.io/{proxy}']
                requestParameters:
                  integration.request.path.proxy: "method.request.path.proxy"
                  # -------------------- this breaks it once added -------------------
                  integration.request.header.x-api-auth: "$context.authorizer.x-api-auth"
                  # ------------------------------------------------------------------
        definitions:
          Empty:
            type: object
          Error:
            type: object
            properties:
              message:
                type: string
        securityDefinitions:
          SfdcAuthorizer:
            type: 'apiKey'
            name: 'Authorization'
            in: 'header'
            x-amazon-apigateway-authtype: 'custom'
            x-amazon-apigateway-authorizer:
              authorizerUri: !Join ['', [!Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/', !FindInMap [EnvironmentMapping, !Ref EnvironmentType, sfdcAuthLambda], '/invocations']]
              authorizerResultTtlInSeconds: !FindInMap [EnvironmentMapping, !Ref EnvironmentType, sfdcAuthTimeout]
              type: 'token'
          ApiKey:
            type: apiKey
            name: x-api-key
            in: header

【问题讨论】:

标签: aws-api-gateway swagger-2.0 openapi lambda-authorizer


【解决方案1】:

嗯...在遵循文档无济于事之后,我变得流氓并从“integration.request.header.x-api-auth”中删除了“$”...并且有效。不知道我对此有何感想。

这是完整的工作 YAML 文件。我将其发布在这里,以防它应该帮助其他人尝试设置采用 PROXY 路径并期望从 Lambda 授权方返回的网关。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Data API pipeline initial Cloudformation template

Mappings:
  EnvironmentMapping:
    alpha:
      certificationArn: ""
      carfaxIpWhitelistRuleId: ""
      hostedZoneId: XYZ
      authLambda: ""
      sfdcAuthLambda: ""
      myApiNetworkLoadBalancer: ""
      sfdcAuthTimeout: 1
    beta:
      certificationArn: ""
      carfaxIpWhitelistRuleId: ""
      hostedZoneId: XYZ
      authLambda: ""
      sfdcAuthLambda: ""
      myApiNetworkLoadBalancer: ""
      sfdcAuthTimeout: 1
    prod:
      certificationArn: ""
      carfaxIpWhitelistRuleId: ""
      hostedZoneId: ABC
      authLambda: ""
      sfdcAuthLambda: ""
      myApiNetworkLoadBalancer: ""
      sfdcAuthTimeout: 1
Parameters:
  EnvironmentType:
    Type: "String"
    AllowedValues:
      - alpha
      - beta
      - prod

Conditions:
  UseProdCondition: !Equals [!Ref EnvironmentType, prod]

Resources:
  MyApiVpcLink:
    Type: AWS::ApiGateway::VpcLink
    Properties:
      Name: MYApiVpcLink
      Description: Allows data-api-gateway to access the VPC that feature-api is on.
      TargetArns:
        - !FindInMap [EnvironmentMapping, !Ref EnvironmentType, myApiNetworkLoadBalancer]

  DataApi:
    DependsOn:
      - MyApiVpcLink
    Type: AWS::Serverless::Api
    Properties:
      Name: !Sub "${EnvironmentType}-data-api"
      StageName: !Ref EnvironmentType
      DefinitionBody:
        swagger: 2.0
        security:
          - ApiKey: []
        info:
          title: !Sub "${EnvironmentType}-data-api"
        paths:
          /sfdc/v1/my-api/{proxy+}:
            x-amazon-apigateway-any-method:
              produces:
                - application/json
              parameters:
                - in: path
                  name: proxy
                  required: true
                  schema:
                    type: string
                - in: header
                  name: x-api-auth
                  required: true
                  schema:
                    type: string
              security:
                - SfdcAuthorizer: []
                  ApiKey: []
              x-amazon-apigateway-api-key-source: HEADER
              x-amazon-apigateway-gateway-responses:
                ACCESS_DENIED:
                  statusCode: 403
                  responseTemplates:
                    application/json: '{\n\"message\": \"Access Denied\"}'
              x-amazon-apigateway-integration:
                httpMethod: ANY
                type: http_proxy
                connectionType: VPC_LINK
                connectionId: !Ref MyApiVpcLink
                passthroughBehavior: when_no_match
                uri: !If [UseProdCondition, 'http://myapp.production.aws-int.myorg.io/{proxy}',!Sub 'http://${EnvironmentType}-myapp.staging.aws-int.myorg.io/{proxy}']
                requestParameters:
                  integration.request.path.proxy: "method.request.path.proxy"
                  integration.request.header.x-api-auth: "context.authorizer.x-api-auth"
        definitions:
          Empty:
            type: object
          Error:
            type: object
            properties:
              message:
                type: string
        securityDefinitions:
          SfdcAuthorizer:
            type: 'apiKey'
            name: 'Authorization'
            in: 'header'
            x-amazon-apigateway-authtype: 'custom'
            x-amazon-apigateway-authorizer:
              authorizerUri: !Join ['', [!Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/', !FindInMap [EnvironmentMapping, !Ref EnvironmentType, sfdcAuthLambda], '/invocations']]
              authorizerResultTtlInSeconds: !FindInMap [EnvironmentMapping, !Ref EnvironmentType, sfdcAuthTimeout]
              type: 'token'
          ApiKey:
            type: apiKey
            name: x-api-key
            in: header

【讨论】:

  • 嘿伙计,也许你能帮帮我。我对 Cloud Formation 有很多经验。但是这个 API 模板、OpenAPI 语法以及像“x-amazon-apigateway-integration”这样的键真的让我很困惑。例如,“x-amazon-apigateway-integration”是什么意思?
  • 嗨@Perimosh,我绝对不是专家,但我认为x-amazon-apigateway-integration 是亚马逊处理OpenAPI 项目的方式。 OpenAPI 提供了动态生成部分 Cloudformation 文件的能力。例如,配置中的“/{proxy+}”表示路径可以是任何东西。并且“x-amazon-apigateway-any-method”生成 YAML 以允许所有 HTTP 方法。
猜你喜欢
  • 2019-11-18
  • 1970-01-01
  • 2017-11-12
  • 2021-10-13
  • 2019-04-22
  • 2017-09-04
  • 1970-01-01
  • 2021-06-23
  • 2019-02-01
相关资源
最近更新 更多