[アップデート] Amazon Cognito のトークン生成前トリガーにイベントバージョン V3 が追加され、M2M 認証でもアクセストークンがカスタマイズできるようになりました

[アップデート] Amazon Cognito のトークン生成前トリガーにイベントバージョン V3 が追加され、M2M 認証でもアクセストークンがカスタマイズできるようになりました

Clock Icon2025.03.05

いわさです。

Amazon Cognito は認証時にカスタム処理を実行することができるタイミングがいくつかあるのですが、その中のひとつ「トークン生成前トリガー」を使うと、ID トークンやアクセストークンをカスタマイズすることができます。
特定のクレームを変更・削除したり、追加のカスタムクレームを設定したり Cognito で JWT 周りに手を入れたいときには必須の機能です。

また、トークン生成前トリガーには「イベントバージョン」という概念があります。
V1 を使うと ID トークンのカスタマイズが可能で、V2 を使うとアクセストークンもカスタマイズできるようになります。
ただし、V2 については以前でいう高度なセキュリティ機能(現在ではエッセンシャル or プラスのユーザープールプラン)が必要でオプション的な位置づけです。[1]

先日、このトークン生成前トリガーに V3 が追加されました。

https://aws.amazon.com/about-aws/whats-new/2025/03/amazon-cognito-access-token-m2m-authorization-flows/

image.png
バージョン3が登場

V3 で何ができるようになったかというと M2M 認証クライアントでもこのトークンカスタマイズができるようになります。(V2 ではできなかった)

V2 との違いですが、利用可能な前提が少しだけ違うので注意が必要です。
ユーザープールプランがエッセンシャルあるいはプラスであれば利用できますが、V2 の場合は以前の高度なセキュリティ機能を有効化した状態から移行したユーザープールでも利用が可能です。
しかし V3 は高度なセキュリティ機能では利用ができずプランのアップグレードが必要です。[2]

今回 M2M 認証で JWT のペイロードがどのように変わるのか検証してみましたので、その様子を紹介します。

検証の様子

まずエッセンシャルプランの Cognito ユーザープールを作成します。

image.png
エッセンシャルでユーザープールを作成

M2M 用のクライアントを作成済みです。カスタムスコープが設定されています。

6B3943BB-DCF4-41D7-B8D5-21769B8B6079.png
カスタムスコープあり

ドメインではリソースサーバーとカスタムスコープをリンク済みです。

70C1A57F-0B04-45B9-B16D-11786331873C.png
Cognitoドメインとリソースサーバーの設定

M2M クライアントを使うとクライアントIDとシークレットで直接アクセストークンを取得することができます。やってみましょう。
なお、以下のクライアントは現在は削除済みです。

% curl -X POST https://ap-northeast-1yufencifl.auth.ap-northeast-1.amazoncognito.com/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=2kq10u0pjfdrq6v6cn60shagri&client_secret=uui84j2ipfd7coi7gv6gn8g53osnkrrt3n2bod7abd4u0faj47n&scope=default-m2m-resource-server-uriplq/read" | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1140  100   962  100   178   4895    905 --:--:-- --:--:-- --:--:--  5816
{
  "access_token": "eyJraWQiOiJoWk9zQjRqem96QWMzS1VcL1lJcTFxUW5XbjJ3WFwvTGhVRG82cU5PXC9pVzdJPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIya3ExMHUwcGpmZHJxNnY2Y242MHNoYWdyaSIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiZGVmYXVsdC1tMm0tcmVzb3VyY2Utc2VydmVyLXVyaXBscVwvcmVhZCIsImF1dGhfdGltZSI6MTc0MTEyMDI5NywiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLmFwLW5vcnRoZWFzdC0xLmFtYXpvbmF3cy5jb21cL2FwLW5vcnRoZWFzdC0xX1lVZmVuQ2lGbCIsImV4cCI6MTc0MTEyMzg5NywiaWF0IjoxNzQxMTIwMjk3LCJ2ZXJzaW9uIjoyLCJqdGkiOiI0YzExYzJjOS1kYTMxLTRhYTAtYmFiMC03M2E0ZjFmOTE2OGEiLCJjbGllbnRfaWQiOiIya3ExMHUwcGpmZHJxNnY2Y242MHNoYWdyaSJ9.jSBbFwsw9NDKxJyYVENwYoikaZcXLpflkS20pUVzM3w4EuFJbOHH7aNfRBC0HfT0jaZRnH7zuC6HoL9shxnvPuCc_Vum0UML65smj3mob7wOqHN1ZX8r3MiCFjhY2Wb_16U4BCefuShbG7UmFuw_TNWBFv_Y3UmwpRhUMLpNsWYstX4c4Un0bup2RfgGyPNFVn3KIYdPhj2A8UGS8K53AzfRGybLSKwik-EkKEX30ZUhiTD2R8ZhtKgOS8rF0K0P6RxDEPPl6SL5rEv8APELDF4xQSr5rn1YHtEIgO4375LwbGRSf9Zs9u2e8sfWSgwtpQq6ieFOwzsljTvFBEiymg",
  "expires_in": 3600,
  "token_type": "Bearer"
}

アクセストークンを取得出来ましたね。
jwt.io あたりで JWT をデコードし、ペイロードデータを確認します。

{
  "sub": "2kq10u0pjfdrq6v6cn60shagri",
  "token_use": "access",
  "scope": "default-m2m-resource-server-uriplq/read",
  "auth_time": 1741120297,
  "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_YUfenCiFl",
  "exp": 1741123897,
  "iat": 1741120297,
  "version": 2,
  "jti": "4c11c2c9-da31-4aa0-bab0-73a4f1f9168a",
  "client_id": "2kq10u0pjfdrq6v6cn60shagri"
}

これが標準のペイロードですね。

トークン生成前トリガーでアクセストークンをカスタマイズする

ということで、ここからはアクセストークンのカスタマイズをします。
Cognito のカスタムトリガーの実体は Lambda です。次のような関数を作成しておきます。今回は ID トークン側の処理は不要ではあるのですが。

index.mjs
export const handler = async (event) => {
  event.response = {
    claimsAndScopeOverrideDetails: {
      idTokenGeneration: {
        claimsToAddOrOverride: {
          hoge1: "hoge1-id",
          hoge2: "hoge2-id",
        },
        claimsToSuppress: ["email"]
      },
      accessTokenGeneration: {
        claimsToAddOrOverride: {
          hoge1: "hoge1-access",
          hoge2: "hoge2-access",
        }
      }
    }
  };

  return event;
};

ユーザープールの拡張機能メニューからトリガータイプに「認証」を選択します。
トークン生成前トリガーを選択し、トリガーイベントバージョンで「基本機能 + ユーザー ID とマシン ID のアクセストークンのカスタマイズ - 推奨」を選択します。推奨なのか。

で、先程作成した Lambda 関数を選択します。

image.png
トークン生成前トリガーとして指定する

上記を設定後にまた先ほどと同じ手順でアクセストークンを取得しましょう。
取得したアクセストークンのペイロード部分を確認します。

{
  "hoge2": "hoge2-access",
  "hoge1": "hoge1-access",
  "sub": "2kq10u0pjfdrq6v6cn60shagri",
  "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_YUfenCiFl",
  "version": 2,
  "client_id": "2kq10u0pjfdrq6v6cn60shagri",
  "token_use": "access",
  "scope": "default-m2m-resource-server-uriplq/read",
  "auth_time": 1741120708,
  "exp": 1741124308,
  "iat": 1741120708,
  "jti": "c635fba3-6227-4fb4-adf9-338b0617bf85"
}

Lambda で設定したカスタムクレームが設定されているのが確認出来ましたね。

さいごに

本日は Amazon Cognito のトークン生成前トリガーにイベントバージョン V3 が追加され、M2M 認証でもアクセストークンがカスタマイズできるようになったので使ってみました。

私は標準のアクセストークンだと足りなくてカスタマイズすることがよくあるのですが、M2M 認証でも使えるようになって良いですね。M2M でカスタマイズできずに独自の仕組みで頑張っていた方はこちらも検討してみてください。

脚注
  1. [アップデート] Amazon Cognito のトークン生成前 Lambda トリガーのトリガーイベントバージョン V2 が使えるようになっていたので試してみた | DevelopersIO ↩︎

  2. [アップデート] Amazon Cognito ユーザープールに機能プランの概念が導入され、料金計算方法が変わります | DevelopersIO ↩︎

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.