Как убедиться, что авторизатор токенов API Gateway вызывается только для определенных путей - PullRequest
1 голос
/ 20 марта 2019

У нас есть API-шлюз, использующий пользовательский Авторизатор токенов . У нас есть 2 лямбды - Привет и GenerateToken .

Мы только хотим, чтобы Greetings лямбда находилась позади авторизатора - требует вызова следующим образом с использованием SAM:

curl -X GET \
  https://<apigatewayid>.execute-api.eu-west-1.amazonaws.com/Prod/generateToken \
  -H 'X-API-KEY: allow'

Как мы можем добиться, чтобы путь GenerateToken не требовал HTTP-токен для аутентификации?

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: API Gateway with Lambda Token Authorizer
Resources:
  GreetingsApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      DefinitionBody:
        swagger: 2.0
        x-amazon-apigateway-policy:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Principal: "*"
              Action: execute-api:Invoke
              Resource:
                - execute-api:/*/*/*
        paths:
          "/hello":
            get:
              x-amazon-apigateway-integration:
                httpMethod: POST
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GreetingsLambda.Arn}/invocations
              responses: {}
          "/generateToken":
            get:
              x-amazon-apigateway-integration:
                httpMethod: POST
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GenerateTokenLambda.Arn}/invocations
              responses: {}
      Auth:
        DefaultAuthorizer: CustomAuthorizer
        Authorizers:
          MyAuthorizer:
            FunctionArn: !GetAtt AuthLambda.Arn
            Identity:
              Header: X-API-KEY

  GenerateTokenLambda:
    Type: AWS::Serverless::Function
    Properties:
      Role: !GetAtt LambdaRole.Arn
      CodeUri: "s3://<bucket-name>/code.zip"
      Handler: src/generateToken.handler
      Events:
        GetRoot:
          Type: Api
          Properties:
            RestApiId: !Ref GreetingsApiGateway
            Path: /generateToken
            Method: get

  GreetingsLambda:
    Type: AWS::Serverless::Function
    Properties:
      Role: !GetAtt LambdaRole.Arn
      CodeUri: "s3://<bucket-name>/code.zip"
      Handler: src/greetings.handler
      Events:
        GetRoot:
          Type: Api
          Properties:
            RestApiId: !Ref GreetingsApiGateway
            Path: /hello
            Method: get

  AuthLambda:
    Type: AWS::Serverless::Function
    Properties:
      Role: !GetAtt LambdaRole.Arn
      CodeUri: "s3://<bucket-name>/code.zip"
      Handler: src/auth.handler

Globals:
  Function:
    Runtime: nodejs8.10

Outputs:
  ApiURL:
    Description: "OUR API URL"
    Value: !Sub "https://${GreetingsApiGateway}.execute-api.${AWS::Region}.amazonaws.com/Prod/"

Ответы [ 2 ]

2 голосов
/ 20 марта 2019

Я не совсем уверен, полностью ли я понял, что вы хотите, но вот шаблон Cloudformation для создания api-gateway ресурсов с включенной авторизацией и без нее.Я использую Cognito User Pool метод авторизации, но он также может быть простым пользовательским авторизатором.

RestAPI:
  Type: AWS::ApiGateway::RestApi
  DeletionPolicy: Delete
  Properties:
    Name: {"Ref": "AWS::StackName"}
    ApiKeySourceType: HEADER
    EndpointConfiguration:
      Types:
        - EDGE

ApiAuthorizer:
  Type: AWS::ApiGateway::Authorizer
  DeletionPolicy: Retain
  DependsOn: UserPoolList
  Properties:
    Name: !Join ["-", [{"Ref": "AWS::StackName"}, "authorizer"]]
    RestApiId: !Ref RestAPI
    Type: COGNITO_USER_POOLS
    AuthType: cognito_user_pools
    IdentitySource: "method.request.header.Authorization"
    ProviderARNs: <User Pool ARN>

ResourceSignin:
  Type: AWS::ApiGateway::Resource
  DeletionPolicy: Delete
  Properties:
    RestApiId: !Ref RestAPI
    ParentId: !GetAtt RestAPI.RootResourceId
    PathPart: "signin"

SigninPostMethod:
  Type: AWS::ApiGateway::Method
  Properties:
    RestApiId: !Ref RestAPI
    ResourceId: !Ref ResourceSignin
    HttpMethod: POST
    AuthorizationType: NONE
    ApiKeyRequired: <true/false>
    Integration:
      Type: AWS_PROXY
      IntegrationHttpMethod: POST
      Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${UserHandlerFunction.Arn}/invocations
      Credentials: !GetAtt GenApiGatewayRole.Arn

ResourceUserCreate:
  Type: AWS::ApiGateway::Resource
  DeletionPolicy: Delete
  Properties:
    RestApiId: !Ref RestAPI
    ParentId: !GetAtt RestAPI.RootResourceId
    PathPart: "create"

CreatePostMethod:
  Type: AWS::ApiGateway::Method
  Properties:
    RestApiId: !Ref RestAPI
    ResourceId: !Ref ResourceUserCreate
    HttpMethod: POST
    AuthorizationType: COGNITO_USER_POOLS
    AuthorizerId: !Ref ApiAuthorizer
    ApiKeyRequired: <true/false>
    Integration:
      Type: AWS_PROXY
      IntegrationHttpMethod: POST
      Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${UserHandlerFunction.Arn}/invocations
      Credentials: !GetAtt UserApiGatewayRole.Arn

Здесь ресурс signin имеет метод POST без авторизации, в то время как ресурс create имеетPOST метод с включенной авторизацией.

Если вы планируете использовать API keys, это может быть единственным возможным способом.Я не смог заставить API keys работать с SAM (я думаю, что API keys с SAM еще не поддерживается - это было около месяца назад, но вы можете перепроверить).

0 голосов
/ 02 апреля 2019

Мы можем добиться этого с помощью swagger в API Gateway:

Лямбда World является публичным API, а лямбда Hello находится за авторизатором AuthLambda


  OurApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Auth:
        Authorizers:
          MyAuthorizer:
            FunctionPayloadType: REQUEST
            FunctionArn: !GetAtt AuthLambda.Arn
      DefinitionBody:
        swagger: 2.0
        basePath: /prod
        info:
          title: AwsSamExample
        x-amazon-apigateway-policy:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Principal: "*"
              Action: execute-api:Invoke
              Resource:
                - execute-api:/*/*/*
        schemes:
          - https
        paths:
          "/hello":
            get:
              x-amazon-apigateway-integration:
                httpMethod: POST
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloLambda.Arn}/invocations
              responses: {}
              security:
                - MyAuthorizer: []
          "/world":
            get:
              x-amazon-apigateway-integration:
                httpMethod: POST
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${WorldLambda.Arn}/invocations
              responses: {}
              security: []


...