kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Lambda オーソライザーのポリシーを簡単に出力できる Powertools for AWS Lambda (Python) の APIGatewayAuthorizerResponse

Amazon API Gateway の Lambda オーソライザー(旧カスタムオーソライザー)を使ってアクセス制御をするときに Lambda オーソライザーの仕様に沿ったポリシーを出力する必要がある💡詳しくは以下のドキュメントに載っている.

docs.aws.amazon.com

今まではドキュメントに載っているコードを参考に実装することが多かったけど,Powertools for AWS Lambda (Python)Event Source Data ClassesAPIGatewayAuthorizerResponse を使うと比較的簡単にポリシーを出力できて良かった❗️

docs.powertools.aws.dev

サンプルコード

今回トークンベースの Lambda オーソライザーで検証したときに使ったコードを載せておく📝

from aws_lambda_powertools.utilities.data_classes import event_source
from aws_lambda_powertools.utilities.data_classes.api_gateway_authorizer_event import (APIGatewayAuthorizerTokenEvent, APIGatewayAuthorizerResponse)
from aws_lambda_powertools.utilities.typing import LambdaContext


@event_source(data_class=APIGatewayAuthorizerTokenEvent)
def lambda_handler(event: APIGatewayAuthorizerTokenEvent, context: LambdaContext):
    arn = event.parsed_arn

    policy = APIGatewayAuthorizerResponse(
        principal_id='user',
        region=arn.region,
        aws_account_id=arn.aws_account_id,
        api_id=arn.api_id,
        stage=arn.stage
    )

    if event.authorization_token == 'allow':
        policy.context = {
            'key1': 'value1',
            'key2': 'value2',
            'key3': 'value3'
        }
        policy.allow_all_routes()
    else:
        policy.deny_all_routes()

    return policy.asdict()

ドキュメントに載っている Authorization ヘッダーに allow という文字列が設定されていれば OK という簡易的な実装だけど,ポリシーを出力するときは APIGatewayAuthorizerResponse に値を設定して allow_all_routes() 関数もしくは deny_all_routes() 関数で出力すれば良くて簡単👍

また認証後に実行される AWS Lambda 関数などに追加情報を渡す場合は context に dict で Key-Value を設定すれば OK👌

docs.aws.amazon.com

動作確認

$ curl -H 'Authorization: allow' ${ENDPOINT}
ok

$ curl -H 'Authorization: deny' ${ENDPOINT}
{"Message":"User is not authorized to access this resource with an explicit deny"}