AWS API Gateway Lambda Authorizer 実践メモ:仕組み・構成・ベストプラクティス

公式ドキュメント[Use API Gateway Lambda authorizers]

Lambda Authorizerとは

API GatewayでAPIへのアクセス制御を行うためのLambda関数です。
クライアントがAPIにリクエストすると、API GatewayはLambda Authorizerを呼び出します。

  • 入力(Input): リクエストに含まれる情報(ヘッダー、クエリ文字列、トークンなど)を元に呼び出し元の「identity(誰か)」を判定
  • 出力(Output): IAMポリシーを返して、そのリクエストを許可するかどうかを制御

カスタム認証スキームを実装でき、以下のような方法を使用可能です:

  • リクエストパラメータからidentityを判別

Authorization Workflow

  1. クライアントが、Bearerトークンやリクエストパラメータを含めて、API Gatewayのメソッドを呼び出す。
  2. API Gatewayは、そのメソッドにLambda Authorizerが設定されているかをチェックする。
  3. Lambda Authorizerが設定されている場合:
    • API GatewayはLambda Authorizer関数を呼び出す。
    • Lambda関数は以下のいずれかの方法で呼び出し元を認証する:
      • OAuthプロバイダーに問い合わせてアクセストークンを確認
      • SAMLプロバイダーに問い合わせてSAMLアサーションを確認
      • リクエストパラメータを元にIAMポリシーを生成
      • データベースから資格情報(クレデンシャル)を取得して確認
    • Lambda関数は以下を返す:
      • IAMポリシー
      • プリンシパルID(識別子)
      • ※ これらを返さない場合は、認証失敗(失敗として扱われる)
  4. API Gatewayは返されたIAMポリシーを評価する。
    • 許可されていない場合:HTTPステータスコード 403 ACCESS_DENIED を返す
    • 許可されている場合:APIメソッドを実行する
  5. 認可キャッシュ(Authorization Caching)が有効な場合:
    • 同じ認証情報を使用する後続リクエストでは、Lambda Authorizerは再度呼び出されない(キャッシュが使用される)

403 ACCESS_DENIED401 UNAUTHORIZED のレスポンスはカスタマイズ可能です。

type

Lambda authorizersは2種類ある

  • Request parameter-based Lambda authorizer
    • REQUEST authorizer と表記する
    • headers や query string parameters を使って「identity(誰か)」を判定する
    • API Gateway は REQUEST authorizer で必要な identity sources がリクエストに含まれるかを検証する
      • もし null または empty の場合は 401 Unauthorized を返す
        • Lambda authorizer は呼び出されない
    • キャッシュキーの一部が変更され、API が redeploy された場合、cached policy は破棄され新たに生成される
    • authorization cachingがturn onの場合
      • 指定された identity source の「すべての値の組み合わせ」がキャッシュキーになる
    • authorization caching を off の場合は
      • リクエストは直接 Lambda authorizer に渡される
  • Token-based Lambda authorizer
    • TOKEN authorizer と表記する
    • bearer token、JSON Web Token (JWT)、OAuth token を使って「identity(誰か)」を判定する
    • authorization caching が on の場合
      • 指定された header name に含まれる token がキャッシュキーになる
    • Additionally
      • 正規表現(RegEx)を使って token の初期検証ができる
        • API Gateway が token を検証し、条件を満たす場合のみ Lambda Authorizer を呼び出す
        • これにより不要な Lambda 呼び出しを減らせる
    • IdentityValidationExpression プロパティは TOKEN authorizer のみに対応している

Example REQUEST or TOKEN authorizer Lambda function

実装例はドキュメントをみてほしい

大事なことは、 以下の2つを必ず設定する必要がある:

  • principalId(呼び出し元ユーザーの識別子)
  • policyDocument(許可または拒否するポリシー)

policyDocument では、Allow の場合に以下のように許可する apiGatewayArn に対して Allow を返す。 Action は “execute-api:Invoke” を指定する。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "execute-api:Invoke",
      "Effect": "Allow",
      "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
    }
  ]
}

optionでcontextにたいを設定すると後続のlambdaで伝播できる。

AWSから提供されているサンプルコード

  1. サンプルアプリケーション
    1. API GatewayとFAPI準拠の外部OIDCプロバイダー、およびLambdaオーソライザーを使って、APIアクセスを保護・認可する方法をデモンストレーション
    2. Open Banking Brazil - Authorization Samples
  2. Custom Authorizer Blueprints
    1. aws-apigateway-lambda-authorizer-blueprints

Configure an API Gateway Lambda authorizer

設定手順については、公式ドキュメントを参照してください。

注意:Lambda関数に対する実行権限(Permission)と、API Gatewayのエンドポイントに対するAuthorizerの設定を忘れずに行ってください。 詳しくはこちらを参照してください。

Input to an API Gateway Lambda authorizer

TOKENREQUEST authorizer それぞれで、eventのinput formatのがそれぞれ異なる

TOKEN

{
    "type":"TOKEN",
    "authorizationToken":"{caller-supplied-token}",
    "methodArn":"arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
}

REQUEST

{
  "type": "REQUEST",
  "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "resource": "/request",
  "path": "/request",
  "httpMethod": "GET",
  "headers": {
    "X-AMZ-Date": "20170718T062915Z",
    "Accept": "*/*",
    "HeaderAuth1": "headerValue1",
    "CloudFront-Viewer-Country": "US",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Is-Mobile-Viewer": "false",
    "User-Agent": "..."
  },
  "queryStringParameters": {
    "QueryString1": "queryValue1"
  },
  "pathParameters": {},
  "stageVariables": {
    "StageVar1": "stageValue1"
  },
  "requestContext": {
    "path": "/request",
    "accountId": "123456789012",
    "resourceId": "05c7jb",
    "stage": "test",
    "requestId": "...",
    "identity": {
      "apiKey": "...",
      "sourceIp": "...",
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "resourcePath": "/request",
    "httpMethod": "GET",
    "apiId": "abcdef123"
  }
}

Output from an API Gateway Lambda Authorizer

Lambda authorizerの出力は、principalIdpolicyDocumentを含むJSON形式で返す必要がある。

  1. principalId

    1. principal identifier
  2. policyDocument

    1. policy document
    2. policy statementsは配列

sample

{
  "principalId": "yyyyyyyy", // The principal user identification associated with the token sent by the client.
  "policyDocument": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "stringKey": "value",
    "numberKey": "1",
    "booleanKey": "true"
  },
  "usageIdentifierKey": "{api-key}"
}

contextは任意の文字列Key-Valueペアを指定でき、後続のLambdaに伝播される。オブジェクトや配列は使用不可。 Lambdaでは$event.requestContext.authorizer.{key}で参照可能(例: stringKey → “value”)。

usageIdentifierKeyUsage Plansを用いる際、対象ユーザーのAPI Keyを指定する。

Resourceの長さは最大1600バイト。超過するとクライアントに414 Request URI too longが返る。これは実行時にのみ判定され、デプロイ前の検出は不可。

Call an API with an API Gateway Lambda authorizer

確認手順については、公式ドキュメントを参照してください。

Configure a cross-account API Gateway Lambda authorizer

今のところやる予定ないからSkip

Control access based on an identity’s attributes with Verified Permissions

What is Amazon Verified Permissions?から始めないとようわからん、今度のTODOとしておく

関連記事