【问题标题】:AWS SAM API with Cognito User Pools authorizer具有 Cognito 用户池授权方的 AWS SAM API
【发布时间】:2018-01-24 19:22:15
【问题描述】:

如何使用AWS SAM 创建一个使用 Cognito 用户池授权方进行授权的 API?

AWS::ApiGateway::Authorizer。但是……

{
  "Type" : "AWS::ApiGateway::Authorizer",
  "Properties" : {
    "AuthorizerCredentials" : String,
    "AuthorizerResultTtlInSeconds" : Integer,
    "AuthorizerUri" : String,
    "IdentitySource" : String,
    "IdentityValidationExpression" : String,
    "Name" : String,
    "ProviderARNs" : [ String, ... ],
    "RestApiId" : String,
    "Type" : String
  }
}

看起来RestApiId 指的是使用这个授权者的API?但是使用 AWS SAM,我的 API 定义为

Resources:
  Ec2Index:
    Type: AWS::Serverless::Function
    Properties:
      Handler: ec2/index.handler
      Runtime: nodejs6.10
      CodeUri: ./src
      FunctionName: 'ApiEc2IndexHandler'
      Description: 'List EC2 resources'
      Timeout: 30
      Role: 'arn:aws:iam::598545985414:role/awsmanagement-lambda-management'
      Events:
        Ec2Index:
          Type: Api
          Properties:
            Path: /ec2
            Method: get

我不明白如何将它们关联在一起?

【问题讨论】:

  • 如果没有 Swagger 模型(显式路线),今天这是不可能的。但是,这里正在跟踪此功能和其他功能:github.com/awslabs/serverless-application-model/issues/248。希望很快我们可以完全依赖隐式 API 定义!
  • @jiew-meng 简而言之,使用 API Authorizer Object 为您的 API 定义一个 Cognito Authorizer。然后,将您的 lambda 函数的 Auth 设置为引用此 API。您可以参考link.medium.com/X6GaTwUjWX了解更多信息。

标签: amazon-web-services amazon-cloudformation amazon-cognito


【解决方案1】:

从 AWS SAM v1.8.0 开始,您可以使用以下语法来执行此操作。您可以参考this article 了解更多信息。

简而言之,使用 API Authorizer Object 为您的 API 定义一个 Cognito Authorizer。然后,将您的 lambda 函数的 Auth 设置为引用此 API。

MyApi:
  Type: AWS::Serverless::Api
  Properties:
    StageName: Prod
    Auth:
      DefaultAuthorizer: MyCognitoAuth # OPTIONAL
      Authorizers:
        MyCognitoAuth:
          # Can also accept an array
          UserPoolArn: !GetAtt MyCognitoUserPool.Arn 
          Identity: # OPTIONAL
            # OPTIONAL; Default: 'Authorization'
            Header: MyAuthorizationHeader 
            # OPTIONAL
            ValidationExpression: myAuthValidationExp
MyFunction:
  Type: AWS::Serverless::Function
  Properties:
    FunctionName: MyFunction
    ...
    Events:
      Post:
        Type: Api
        Properties:
          Path: /compute
          Method: POST
          RestApiId: !Ref MyApi
          Auth:
            Authorizer: MyCognitoAuth

【讨论】:

    【解决方案2】:

    您可以将您的 Cognito 用户授权者直接添加到您的 SAM AWS::Serverless::Api

      MyApi:
        Type: AWS::Serverless::Api
        Properties:
          StageName: Prod
          Cors: "'*'"
          Auth:
            DefaultAuthorizer: MyCognitoAuthorizer
            Authorizers:
              MyCognitoAuthorizer:
                UserPoolArn: 'arn:aws:cognito-.....' # YOUR COGNITO USER POOL ARN
    

    如果你没有设置默认的,你可以在你的AWS::Serverless::Function 上添加一个函数授权者。或者您可以使用Authorizer: 'NONE' 将其停用。

    Auth:
      Authorizer: MyCognitoAuthorizer
    

    另见documentation

    【讨论】:

    • 为什么需要Authorized in the Function?这是必要的还是仅仅在 API 中创建一个授权方就足够了?
    • 在函数中添加Authorizer key 如果你将它添加到API资源中,它并不是真正需要的。但是,请记住将RestApiId 添加到函数中。
    【解决方案3】:

    正如@simones 提到的,以下将创建 Cognito 用户池授权方(CF 模板)。

    ApiCognitoAuthorizer:          
     Type: AWS::ApiGateway::Authorizer
     Properties:
      IdentitySource: 'method.request.header.Authorization'
      Name: ApiCognitoAuthorizer
      ProviderARNs:
       - 'arn:aws:cognito-idp:{region}:{userpoolIdentifier}'
      RestApiId: !Ref ServerlessRestApi
      Type: COGNITO_USER_POOLS
    

    要将其附加到资源方法,以下工作(在 Swagger 文件中):

     securityDefinitions:
      ApiCognitoAuthorizer:
        type: apiKey
        name: Authorization
        in: header
        x-amazon-apigateway-authtype: cognito_user_pools
        x-amazon-apigateway-authorizer:
          type: cognito_user_pools
          providerARNs:
            - arn:aws:cognito-idp:{region}:{userpoolIdentifier}
    

    然后,添加到特定方法(在 Swagger 文件中):

        security:
        - ApiCognitoAuthorizer: []
    

    【讨论】:

      【解决方案4】:

      您现在可以使用“ServerlessRestApi”引用隐式创建的 api 网关。 因此,在您的 SAM 模板中添加这段常规 Cloudformation,一切都会正常运行

      ApiCognitoAuthorizer:          
        Type: AWS::ApiGateway::Authorizer
        Properties:
          IdentitySource: 'method.request.header.Authorization'
          Name: ApiCognitoAuthorizer
          ProviderARNs:
            - 'arn:aws:cognito-idp:{region}:{userpoolIdentifier}'
          RestApiId: !Ref ServerlessRestApi
          Type: COGNITO_USER_POOLS
      

      【讨论】:

      • 这正确地将认知授权者附加到网关,但是有没有办法将其作为授权者分配给 SAM 模板中的特定功能?
      【解决方案5】:

      我不确定您是否可以在 SAM 中指定授权人,但您可以将 Swagger 嵌入可以执行此操作的 SAM 文件中。这是 2 月 17 日的新功能 [ref]。

      我绝对不是 Swagger 或 SAM 方面的专家,但您似乎想要这样的东西:

      AWSTemplateFormatVersion: '2010-09-09'
      Transform: AWS::Serverless-2016-10-31
      Description: Simple API Endpoint configured using Swagger specified inline and backed by a Lambda function
      Resources:
         Ec2Index:
           Type: AWS::Serverless::Api
          Properties:
              StageName: <stage>
              DefinitionBody:
                  swagger: 2.0
                  info:
                    title:
                      Ref: AWS::StackName
                  securityDefinitions:
                    cognitoUserPool:
                      type: apiKey,
                      name: "Authorization"
                      in: header
                      x-amazon-apigateway-authtype: cognito_user_pools
                      x-amazon-apigateway-authorizer:
                        type: cognito_user_pools
                        providerARNs:
                          - arn:aws:cognito-idp:${AWS::Region}:{AWS::AccountId}:userpool/<user_pool_id>
                  paths:
                    "/ec2":
                      get:
                        security:
                          - cognitoUserPool: []
                        x-amazon-apigateway-integration:
                          httpMethod: POST
                          type: aws_proxy
                          uri:
                            Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Ec2IndexLamb.Arn}/invocations
                        responses: {}
                  swagger: '2.0'
         Ec2IndexLamb:
          Type: AWS::Serverless::Function
          Properties:
            Handler: ec2/index.handler
            Runtime: nodejs6.10
            CodeUri: ./src
            FunctionName: 'ApiEc2IndexHandler'
            Description: 'List EC2 resources'
            Timeout: 30
            Role: 'arn:aws:iam::598545985414:role/awsmanagement-lambda-management'
            Events:
              Ec2Index:
                Type: Api
                Properties:
                  Path: /ec2
                  Method: get
      

      参考资料:

      https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html#apigateway-enable-cognito-user-pool

      https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/inline_swagger/template.yaml


      编辑:修复了“安全”部分的 Swagger 2.0 语法,它应该是一个列表。

      【讨论】:

        猜你喜欢
        • 2020-05-18
        • 2017-09-04
        • 2020-11-27
        • 1970-01-01
        • 2021-10-08
        • 2017-10-25
        • 2022-11-10
        • 1970-01-01
        • 2018-11-19
        相关资源
        最近更新 更多