いくつかの異なるサービス/サーバーレススタック間で共有されるカスタム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
サーバーレス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
上記の回答がうまくいかなかったので、これが私の設定方法です。それは誰かのために役立つかもしれません。
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です。
共有カスタム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'