AWS CDK でLambdaオーソライザー(リクエスト)を実装して認証を試してみた

AWS CDK でLambdaオーソライザー(リクエスト)を実装して認証を試してみた

2025.08.17

こんにちは!製造ビジネステクノロジー部の小林です。

前回の記事では、Lambdaオーソライザーのイベントペイロード「トークン」を利用して、シンプルな認証機能を実装しました。
https://dev.classmethod.jp/articles/shoma-aws-cdk-lambda-authorizer-token-implement-authentication-verify/

今回は、Lambdaオーソライザーのイベントペイロード「リクエスト」を利用した認証機能をAWS CDKを用いて検証してみました。

Lambdaオーソライザーとは?

Lambdaオーソライザーは、API Gatewayがバックエンドにリクエストを送る前に、認証・認可のロジックを実行するための機能です。これは、認証情報を検証するためのLambda関数と、その関数が返すIAMポリシーとの組み合わせで動作します。
スクリーンショット 2025-08-13 0.27.23
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

イベントペイロードのリクエストとは?

Lambdaオーソライザーのイベントペイロード「リクエスト」タイプは、複数のIDソース(ヘッダー、クエリ文字列、ステージ変数など)に基づいて、認証・認可のロジックを実行する機能です。トークンベースのオーソライザーと比べて、複数の認証情報を扱うことができます。

  • トークン
    • 単一のヘッダー(例:Authorization)
  • リクエスト
    • クエリ文字列、ステージ変数、コンテキスト変数など

例えばAPIキーによる認証を行っている場合、特定のAPIキーがヘッダーに含まれていることに加えて、クエリ文字列に特定のユーザーIDが含まれている場合のみアクセスを許可する、といった複雑な認証要件にも対応できます。

やってみた

実際にLambdaオーソライザーのイベントペイロード「リクエスト」タイプの機能を試してみます。

前提

本記事では、API Gateway の REST API を利用します。
リソースは、AWS CDK を利用して構築します。

概要図

request-authorizer/
├── bin/
│   └── request-authorizer.ts
├── lib/
│   └── request-authorizer-stack.ts
├── lambda/
│   ├── request-authorizer.ts
│   └── backend.ts
...

1. Lambdaオーソライザー関数の作成

認証ロジックを記述するLambda関数を、リクエストタイプに合わせて作成します。この関数は、リクエストのヘッダーとクエリ文字列から認証情報を取得します。

lambda/request-authorizer.ts
import { APIGatewayRequestAuthorizerEvent, APIGatewayAuthorizerResult } from 'aws-lambda';

export const handler = async (event: APIGatewayRequestAuthorizerEvent): Promise<APIGatewayAuthorizerResult> => {
  // ① 認証に必要な情報をリクエストから取得
  const apiKey = event.headers?.['x-api-key'];
  const user = event.queryStringParameters?.['user'];

  // ② 認証ロジックの実行
  let effect: 'Allow' | 'Deny';
  let principalId: string;

  if (apiKey === 'request-key' && user === 'test-user') {
    // 認証情報が正しい場合
    effect = 'Allow';
    principalId = user;
  } else {
    // 認証情報が不正な場合
    effect = 'Deny';
    principalId = 'unknown-user';
  }

  // ③ IAMポリシーを返す
  return {
    principalId: principalId,
    policyDocument: {
      Version: '2012-10-17',
      Statement: [{
        Action: 'execute-api:Invoke',
        Effect: effect,
        Resource: event.methodArn,
      }],
    },
  };
};

このソースでは、APIGatewayRequestAuthorizerEventという型を利用することで、headersやqueryStringParametersにアクセスできます。複数の条件を満たす場合にのみAllowポリシーを返すよう、ロジックを実装しています。

2. バックエンドLambdaのソース

この関数は、オーソライザーの認証を通過したリクエストのみが実行されます。

lambda/backend.ts
import { APIGatewayProxyResult } from 'aws-lambda';

export const handler = async (): Promise<APIGatewayProxyResult> => {
  return {
    statusCode: 200,
    body: JSON.stringify({ message: 'Hello from a protected API!' }),
  };
};

3. AWS CDKによるインフラの定義

AWS CDKを使って、API Gateway、Lambda関数などをまとめて定義します。

request-authorizer-stack.ts
import { Stack, StackProps, aws_apigateway as apigw } from 'aws-cdk-lib';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import { Construct } from 'constructs';
import * as path from 'path';

// import * as sqs from 'aws-cdk-lib/aws-sqs';

export class RequestAuthorizerStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // バックエンドLambda関数の定義 (変更なし)
    const backendFunction = new NodejsFunction(this, 'BackendFunction', {
      runtime: Runtime.NODEJS_22_X,
      entry: path.join(__dirname, '..', 'lambda', 'backend.ts'),
      handler: 'handler',
    });

    // Lambdaオーソライザー関数の定義
    const authorizerFunction = new NodejsFunction(this, 'AuthorizerRequestFunction', {
      runtime: Runtime.NODEJS_22_X,
      entry: path.join(__dirname, '..', 'lambda', 'request-authorizer.ts'),
      handler: 'handler',
    });

    // API Gatewayの定義
    const api = new apigw.RestApi(this, 'MyProtectedRequestApi', {
      restApiName: 'MyProtectedRequestApi',
      description: 'API protected by a Lambda request authorizer',
    });

    // Lambdaオーソライザーの定義
    const authorizer = new apigw.RequestAuthorizer(this, 'MyLambdaRequestAuthorizer', {
      handler: authorizerFunction,
      identitySources: ['method.request.header.x-api-key', 'method.request.querystring.user'],
    });

    // バックエンド統合とメソッドの定義
    const backendIntegration = new apigw.LambdaIntegration(backendFunction);
    const helloResource = api.root.addResource('hello');
    helloResource.addMethod('GET', backendIntegration, {
      authorizer: authorizer,
    });
  }
}

認証情報の取得元を指定する

identitySourcesプロパティ(Lambdaオーソライザー関数の定義部分)は、Lambdaオーソライザーが認証情報を取得する場所を指定する設定です。

  • 'method.request.header.x-api-key': APIリクエストのヘッダーにあるx-api-keyという名前の値を認証情報として使用します。
  • 'method.request.querystring.user': APIリクエストのクエリ文字列にあるuserという名前の値を認証情報として使用します。

この設定をすることで、API Gatewayはこれらのパラメータをリクエストから抽出し、オーソライザーのLambda関数に渡してくれます。Lambda関数側では、これらの情報がevent.headersやevent.queryStringParametersとして利用できます。
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-lambda-authorizer.html#http-api-lambda-authorizer.identity-sources

以上でリソースの作成は完了です!さっそくデプロイしてみましょう!

動作確認

デプロイが完了したら、AWSコンソールで作成されたリソースを確認してみます。
スクリーンショット 2025-08-17 17.58.33
Lambdaオーソライザーのイベントペイロードが「リクエスト」として作成されていますね。

では、実際にAPIを呼び出して、認証が正しく動作するか確認してみます。curlコマンドを使って動作を確認します。{API_ID}はデプロイされたAPIのエンドポイントIDに置き換えてください。

1. 条件を満たさない場合(失敗パターン)

以下のリクエストは、identitySourcesで必須に設定したクエリ文字列(userパラメータ)がリクエストに含まれていないため、401 Unauthorizedが返されます。

curl -i -X GET "https://{API_ID}.execute-api.ap-northeast-1.amazonaws.com/prod/hello" -H "x-api-key: request-key"

結果

HTTP/2 401 
~省略
{"message":"Unauthorized"}% 

2. 両方の条件を満たす場合(成功パターン)

正しいAPIキーヘッダーと必須のクエリ文字列を両方含めることで、オーソライザーがAllowポリシーを返し、バックエンドのLambda関数が正常に実行されます。

curl -i -X GET "https://{API_ID}.execute-api.ap-northeast-1.amazonaws.com/prod/hello?user=test-user" -H "x-api-key: request-key"

結果

HTTP/2 200
〜省略
{"message":"Hello from lambda API!"}

コンソールから動作確認

スクリーンショット 2025-08-17 18.38.46

おわりに

今回は、API GatewayのLambdaオーソライザー(リクエスト)を利用して、複数のパラメータを組み合わせた認証機能を検証してみました。イベントペイロードでリクエスト型を選択することで、単一の認証要素では実現できない、細かい制御が可能になりましたね。この記事がLambdaオーソライザーの利用を検討している方のお役に立てば幸いです。

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.