web-dev-qa-db-ja.com

ServerlessFrameworkでの共有Lambdaオーソライザーのセットアップ

いくつかの異なるサービス/サーバーレススタック間で共有されるカスタムLambdaオーソライザーを作成しようとしています。ここのドキュメントを理解している場合 https://serverless.com/framework/docs/providers/aws/events/apigateway/#note-while-using-authorizers-with-shared-api-gateway 、つまり、「共通リソース」サービス/サーバーレススタックに共有承認者リソースを作成してから、他のサービスからその共有承認者を参照する必要があります。まず第一に:私の理解は正しいですか?

私の理解が正しければ、次の質問は次のようになります。これを行うにはどうすればよいですか。ドキュメントにはラムダオーソライザーの明確な例が記載されていないため、カスタマイズを試みた方法は次のとおりです。

functions:
authorizerFunc:
handler: authorizer/authorizer.handler
runtime: nodejs8.10

resources:
Resources:
authorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
AuthorizerResultTtlInSeconds: 0
Name: Authorizer
Type: REQUEST
AuthorizerUri: ???
RestApiId:
Fn::ImportValue: myRestApiId

AuthorizerUriの構文がどうあるべきかわかりません。 「Ref:authorizerFunc」、「Fn :: GetAtt:[authorizerFunc、Arn]」などを試しましたが役に立ちませんでした。

AuthorizerUriが機能するようになったら、承認者リソースの出力を追加してから、APILambdaを含むサービスからFn :: ImportValueを追加しますか?

後世のためのサーバーレスフォーラムでの私の質問へのリンク: https://forum.serverless.com/t/shared-lambda-authorizer/6447

6
Dan

サーバーレス1.35.1このスレッドに出くわした人のために、ここに新しい方法があります

ユーザープールを作成する場所ならどこでも、先に進んでApiGatewayAuthorizerを追加できます。

# create a user pool as normal
CognitoUserPoolClient:
  Type: AWS::Cognito::UserPoolClient
  Properties:
    # Generate an app client name based on the stage
    ClientName: ${self:custom.stage}-user-pool-client
    UserPoolId:
      Ref: CognitoUserPool
   ExplicitAuthFlows:
   - ADMIN_NO_SRP_AUTH
   GenerateSecret: true

# then add an authorizer you can reference later
ApiGatewayAuthorizer:
  DependsOn:
  # this is pre-defined by serverless
  - ApiGatewayRestApi
  Type: AWS::ApiGateway::Authorizer
  Properties:
    Name: cognito_auth
    # apparently ApiGatewayRestApi is a global string
    RestApiId: { "Ref" : "ApiGatewayRestApi" }
    IdentitySource: method.request.header.Authorization
    Type: COGNITO_USER_POOLS
    ProviderARNs:
    - Fn::GetAtt: [CognitoUserPool, Arn]

次に、関数を定義するとき

graphql:
  handler: src/app.graphqlHandler
  events:
  - http:
    path: /
    method: post
    cors: true
    integration: lambda
    # add this and just reference the authorizer
    authorizer:
      type: COGNITO_USER_POOLS
      authorizerId:
        Ref: ApiGatewayAuthorizer
0
sevensevens

上記の回答がうまくいかなかったので、これが私の設定方法です。それは誰かのために役立つかもしれません。

resources:
  Resources:
    ApiGatewayAuthorizer:
      Type: AWS::ApiGateway::Authorizer
      Properties:
        AuthorizerResultTtlInSeconds: 0
        IdentitySource: method.request.header.Authorization
        AuthorizerUri:
          Fn::Join: ["",
            [
              "arn:aws:apigateway:",
              "${self:custom.region}",
              ":lambda:path/",
              "2015-03-31/functions/",
              Fn::GetAtt: ["YourFunctionNameLambdaFunction", "Arn" ],
              "/invocations"
            ]]
        RestApiId:
          Fn::ImportValue: ${self:custom.stage}-ApiGatewayRestApiId
        Name: api-${self:custom.stage}-authorizer 
        Type: REQUEST
    ApiGatewayAuthorizerPermission:
      Type: AWS::Lambda::Permission
      Properties:
        FunctionName:
          Fn::GetAtt: ["YourFunctionNameLambdaFunction", "Arn"]
        Action: lambda:InvokeFunction
        Principal:  
          Fn::Join: ["",["apigateway.", { Ref: "AWS::URLSuffix"}]]

  Outputs:
    AuthorizerRef:
      Value:
        Ref: ApiGatewayAuthorizer
      Export:
        Name: authorizer-ref:${self:custom.stage}

APIゲートウェイを追加してここにインポートする方法を知っているといいのですが

RestApiId:
      Fn::ImportValue: ${self:custom.stage}-ApiGatewayRestApiId

、受け入れられた回答ですでに指定されているため

そして私の場合、承認タイプとしてイベントヘッダーに値を渡して、承認ラムダ関数で取得しました。私のタイプはREQUESTです。

0
BKM

共有カスタムAPIGateway Lambda Authorizerへの変更は、サービスの一部として機能するようになると簡単でした。その時点では、デプロイされたラムダ(オーソライザー)にarn:を追加し、サービスから別のデプロイ可能なサービスに「オーソライザー」定義を削除するだけでした。

  myLambdaName:
    handler: handler.someNodeFunction
    name: something-someNodeFunction
    events:
      - http:
          path: /path/to/resource
          method: get
          cors: true
          authorizer: 
            name: myCustomAuthorizer
            # forwarding lambda proxy event stuff to the custom authorizer
            IdentitySource: method.request.header.Authorization, context.path
            type: request
            arn:  'arn:aws:lambda:region:##:function:something-else-myCustomAuthorizer'

次に、他の「サービス」には、デプロイされた複数のマイクロサービスによって共有されるいくつかのカスタム承認者があります。

functions:

  myCustomAuthorizer:
    name: something-else-myCustomAuthorizer
    handler: handler.myCustomAuthorizer

サイドノート:

「authorization:bearer xyzsddfsf」を単純なイベントとして転送するトークンタイプの承認者が必要な場合は、次のようにします。

{
    "type": "TOKEN",
    "methodArn": "arn:aws:execute-api:region:####:apigwIdHere/dev/GET/path/to/resource",
    "authorizationToken": "Bearer ...."
}
          authorizer: 
            arn:  'arn:aws:lambda:region:##:function:something-else-myCustomAuthorizer'
0
lko