2

我们有一个使用自定义令牌授权者的 API 网关。我们有 2 个 lambdas - GreetingsGenerateToken

我们只希望Greetings lambda 在授权者之后 - 需要使用 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/"
4

3 回答 3

2

我不太确定我是否完全理解您想要什么,但这里有一个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 - 这是大约一个月前,但您可以仔细检查)。

于 2019-03-20T19:52:11.793 回答
0

我们可以通过 API Gateway 中的 swagger 来实现这一点:

World lambda 是一个公共 API,Hello lambda位于 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: []


于 2019-04-02T16:27:00.293 回答
0

使用无服务器框架,只需一个属性即可轻松管理它。 https://www.npmjs.com/package/serverless

于 2019-08-27T06:14:28.380 回答