1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【OAuth 2.0】Cognitoの「クライアント資格情報」を使って、API Gateway + Lambdaのシステム間認証を実装する

1
Posted at

Amazon Cognito + API Gateway + Lambdaで構築するM2M(Client Credentials)認証ハンズオン

システム間の連携(Machine to Machine: M2M)で、APIを安全に保護するために OAuth 2.0のClient Credentials(クライアント資格情報)フロー を使用するケースが増えています。

今回は、Amazon Cognito でM2Mクライアント(ユーザープール)を作成してアクセストークンを取得し、それを API Gateway のCognitoオーソライザーで検証して AWS Lambda を安全に呼び出す構成をハンズオン形式で解説します。

全体構成図

構成は非常にシンプルです。

  1. クライアント(外部システム等)がCognitoの認可エンドポイントへ client_idclient_secret を送信。
  2. Cognitoから アクセストークン(JWT)が返却される。
  3. クライアントは Authorization ヘッダーにトークンを含めてAPI Gatewayへリクエスト。
  4. API GatewayのCognitoオーソライザーがトークンを検証し、有効であれば後続のLambdaを実行。

Step 1: Amazon Cognito の設定

まずは認証基盤となるCognitoユーザープールと、M2M用のクライアントを設定します。

1.1 ユーザープールの作成

  1. AWSコンソールでCognitoを開き、「ユーザープールの作成」をクリック。
  2. 属性プロバイダーで 「ユーザー名」(デフォルト)を選択して次へ。
  3. パスワードポリシー等は検証用のためデフォルトのままで次へ。
  4. 「多要素認証 (MFA)」は 「MFA なし」 を選択して次へ。
  5. 「ユーザープール名」を入力(例: m2m-test-pool)。

1.2 アプリクライアントの設定(ここが重要!)

「アプリケーション初期設定」のステップで、M2M用の設定を行います。

  1. アプリケーションタイプ: 「従来のWebアプリケーション」 or 「機密クライアント」 を選択。
  2. アプリケーションクライアント名: m2m-client
  3. 「クライアントシークレットを生成する」 にチェックが入っていることを確認。

1.3 認証フローとスコープの設定

ユーザープール作成後、作成したプールを開き、「アプリケーションの統合」 タブの一番下にある「アプリケーションクライアント」を開きます。

  1. ホストされたUI(Hosted UI) の設定で「編集」をクリック。
  2. 以下の通り設定します。
    • マネージド型ログイン(またはホストされたUI): 有効
    • OAuth 2.0 の付与タイプ: 「クライアント資格情報 (Client credentials)」 にチェック(※他のチェックは外す)
    • カスタムスコープ / OAuthスコープ: openid などの標準スコープ、または必要に応じてカスタムスコープを指定。
  3. 「Cognito ドメイン」 を設定します(例: https://m2m-test-auth.auth.ap-northeast-1.amazoncognito.com)。

Step 2: AWS Lambda の作成

API Gatewayから呼び出されるバックエンドのLambda関数を作成します。

  1. Lambdaコンソールから「関数の作成」をクリック。
  2. 関数名: m2m-test-function
  3. ランタイム: Node.js(または任意の言語)
  4. コードは以下のようなシンプルなレスポンスを返すようにします。
export const handler = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            message: "Hello from M2M Protected Lambda!",
            caller: event.requestContext.authorizer?.claims?.client_id || "Unknown"
        }),
    };
    return response;
};

Step 3: Amazon API Gateway の設定

APIを作成し、Cognitoによる認証(オーソライザー)を設定します。

3.1 REST APIの作成

  1. API Gatewayコンソールで「APIを作成」> 「REST API」 を選択。
  2. API名: m2m-protected-api

3.2 オーソライザーの作成

  1. 左メニューの 「オーソライザー」 を選択し、「新しいオーソライザーの作成」をクリック。
  2. 設定項目:
    • 名前: CognitoM2MAuthorizer
    • タイプ: 「Cognito」
    • Cognitoユーザープール: Step 1で作成したプールを選択。
    • トークンのソース: Authorization
  3. 「作成」をクリック。

3.3 リソースとメソッドの作成

  1. 左メニューの 「リソース」 に戻り、「メソッドの作成」をクリック。
  2. メソッドタイプ: GET
  3. 統合タイプ: Lambda 関数 > Step 2で作成した m2m-test-function を選択。
  4. 作成された GET メソッドの画面で 「メソッドリクエスト」 の「編集」をクリック。
  5. 「認可」 で、先ほど作成した CognitoM2MAuthorizer を選択して保存。

3.4 APIのデプロイ

  1. 「APIをデプロイ」をクリック。
  2. ステージ名: prod を作成。
  3. 発行された 「URLの呼び出し」(例: https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod)を控えておきます。

Step 4: 動作確認

それでは、実際にトークンを取得してAPIにアクセスしてみましょう。

1. トークンの取得 (Client Credentials Flow)

cURLを使って、Cognitoのドメインからアクセストークンを発行します。
YOUR_DOMAIN, CLIENT_ID, CLIENT_SECRET はご自身の環境に置き換えてください。

# クライアントIDとシークレットをBase64エンコードして渡すか、cURLの-uオプションを使用します
curl -X POST "https://<YOUR_COGNITO_DOMAIN>[.auth.ap-northeast-1.amazoncognito.com/oauth2/token](https://.auth.ap-northeast-1.amazoncognito.com/oauth2/token)" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "<CLIENT_ID>:<CLIENT_SECRET>" \
  -d "grant_type=client_credentials"

レスポンス例:
成功すると、以下のように access_token が返ってきます。

{
  "access_token": "eyJraWQiOi...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

2. トークンなしでAPI Gatewayにアクセス(拒否されることを確認)

まずはヘッダーなしでAPIを叩いてみます。

curl -i https://<API_ID>[.execute-api.ap-northeast-1.amazonaws.com/prod/](https://.execute-api.ap-northeast-1.amazonaws.com/prod/)

レスポンス:

HTTP/1.1 401 Unauthorized
{"message":"Unauthorized"}

しっかりブロックされていますね。

3. トークン付きでAPI Gatewayにアクセス(成功)

先ほど取得した access_tokenAuthorization ヘッダーに付与してリクエストします。

curl -i -H "Authorization: Bearer <取得したaccess_token>" \
  https://<API_ID>[.execute-api.ap-northeast-1.amazonaws.com/prod/](https://.execute-api.ap-northeast-1.amazonaws.com/prod/)

レスポンス:

HTTP/1.1 200 OK
{
  "message": "Hello from M2M Protected Lambda!",
  "caller": "xxxxxxxxxxxxxxxxxxxxxxxxxx"
}

無事にLambdaが実行され、呼び出し元のクライアントIDが取得できていることが確認できました!

まとめ

Amazon Cognitoの「クライアント資格情報 (Client credentials)」フローを活用することで、面倒なJWTの検証ロジックを自前で実装することなく、API Gatewayの標準機能だけで安全なM2M認証を実現できました。

システム間連携のAPIをAWS上で構築する際は、ぜひ参考にしてみてください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?