Отключение защиты для конечной точки ресурса одного метода в шлюзе API с помощью шаблона AWS SAM - PullRequest
2 голосов
/ 08 января 2020

Я использую AWS Без сервера для создания шлюза API, поддерживаемого функциями Lambda.

У меня определены следующие ресурсы и методы:

/projects
   -> GET (should require API key)
   -> OPTIONS (should not, since it is used for CORS preflight)

У меня проблемы с CORS и мне требуется ключ API. Код клиентского интерфейса получает ошибку 403 Forbidden, когда он инициирует предварительный запрос CORS OPTIONS, поскольку API Key Required в консоли управления AWS имеет значение True для метода OPTIONS.

Я хочу отключить защиту специально для запроса OPTIONS, но сохранить его для всех других методов (GET, POST и т. Д. c.). Вот мои определения ресурсов (вы можете видеть, что я установил значение по умолчанию ApiKeyRequired: true в моем Auth объекте:

  MyApi:
    Type: 'AWS::Serverless::Api'
    Name: MyApi
    Properties:
      Auth:
        AddDefaultAuthorizerToCorsPreflight: true
        ApiKeyRequired: true # sets for all methods
      Cors:
        AllowCredentials: true
        AllowHeaders: '"Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token"'
        AllowMethods: '"POST,GET,OPTION"'
        AllowOrigin: '"*"'
        MaxAge: '"600"'
      StageName: !Ref StageName
      DefinitionBody:
        swagger: 2.0
        info:
          title: !Sub API-Lambda-${StageName}
          description: "API for MyApi"
          version: "1.0.0"
        paths:
          /projects:
            get:
              produces:
                - application/json
              responses:
                "200":
                  description: OK
              x-amazon-apigateway-any-method:
                produces:
                  - application/json
              x-amazon-apigateway-integration:
                httpMethod: post
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetAllProjectsFunction.Arn}/invocations
            options:
              consumes:
                - application/json
              produces:
                - application/json
              responses:
                '200':
                  description: 200 response
                  headers:
                    Access-Control-Allow-Origin:
                      type: string
                    Access-Control-Allow-Methods:
                      type: string
                    Access-Control-Allow-Headers:
                      type: string
              x-amazon-apigateway-integration:
                responses:
                  default:
                    statusCode: 200
                    responseParameters:
                      method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
                      method.response.header.Access-Control-Allow-Headers: "'Content-Type,mode,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
                      method.response.header.Access-Control-Allow-Origin: "'*'"
                passthroughBehavior: when_no_match
                requestTemplates:
                  application/json: "{\"statusCode\": 200}"
                type: mock
          /projects/{userId}:
            get:
              responses:
                "200":
                  description: OK
              x-amazon-apigateway-any-method:
                produces:
                  - application/json
              x-amazon-apigateway-integration:
                httpMethod: post
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetProjectsForUserFunction.Arn}/invocations
            options:
              consumes:
                - application/json
              responses:
                '200':
                  description: 200 response
                  headers:
                    Access-Control-Allow-Origin:
                      type: string
                    Access-Control-Allow-Methods:
                      type: string
                    Access-Control-Allow-Headers:
                      type: string
              x-amazon-apigateway-integration:
                responses:
                  default:
                    statusCode: 200
                    responseParameters:
                      method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
                      method.response.header.Access-Control-Allow-Headers: "'Content-Type,mode,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
                      method.response.header.Access-Control-Allow-Origin: "'*'"
                passthroughBehavior: when_no_match
                requestTemplates:
                  application/json: "{\"statusCode\": 200}"
                type: mock

Я знаю, что в документации Swagger сказано, что я могу переопределить безопасность добавив объект security для каждого метода ресурса. В этой записи SO также предлагается отключить защиту, сделав объект security пустым списком.

Однако я попробовал следующее подходы:

        options:
          consumes:
            - application/json
          produces:
            - application/json
          security:
            -
          responses: ...

А также просто превращение security в объект None:

        options:
          consumes:
            - application/json
          produces:
            - application/json
          security:
          responses: ...

В обоих случаях я получаю следующую ошибку при попытке развернуть с помощью aws sam deploy:

Ожидание создания набора изменений .. Ошибка: Не удалось создать набор изменений для стека: my-app, например: Ошибка Waiter ChangeSetCreateComplete: Официант обнаружил состояние ошибки терминала Статус: СБОЙ. Причина: преобразование AWS :: Serverless-2016-10-31 завершился с ошибкой: Внутренняя ошибка преобразования.

Кажется, что мое определение security неверно. Как отключить защиту для одного метода ресурса ( а именно метод OPTIONS)?

ОБНОВЛЕНИЕ:

Я получил шаблон для развертывания, используя следующий синтаксис:

    options:
      consumes:
        - application/json
      produces:
        - application/json
      security:
        - {}
      responses:

Однако даже после развертывания у меня все еще есть в консоли:

enter image description here

Я, честно говоря, сейчас в растерянности, потому что это так легко сделать с обычным ресурсом AWS::ApiGateway::Method (просто установите для ApiKeyRequired значение true).

1 Ответ

1 голос
/ 04 апреля 2020

Не очень хорошо, но я думаю, вам придется отключить api_key для каждого метода OPTIONS - предоставьте определение метода с помощью openapi и пропустите / пропустите ключ 'security' *

...