Amazon CognitoのフェデレーションLambdaトリガーでGoogle認証した時の属性をカスタマイズしてみる

Amazon CognitoのフェデレーションLambdaトリガーでGoogle認証した時の属性をカスタマイズしてみる

CognitoのフェデレーションLambdaトリガーを使って、Google認証時の属性をカスタマイズしてみました。E-mailからドメイン部分を抽出してカスタム属性にマッピングする例を紹介します。
2026.02.02

はじめに

Amazon Cognitoユーザープールは特定のイベント処理をカスタマイズできる、Lambdaトリガーという機能があります。

先日のアップデートで新しいトリガータイプ「フェデレーション」が追加されました。詳しくは、弊社のブログを御覧ください。

https://dev.classmethod.jp/articles/amazon-cognito-inbound-federation-lambda-trigger/

このフェデレーションLambdaトリガーを実際に使って、Googleから取得できる属性を確認し、カスタマイズしてみようと思います。

フェデレーション Lambda トリガーとは

外部IdP(SAMLまたはOIDC)からの認証レスポンスを受け取った後、ユーザープールに属性を保存する前にLambda関数を実行できる機能です。
外部IdPから受け取った属性から不要な情報を削除したり、加工したりすることが可能です。

lambda-inbound-federation

※画像引用:Inbound federation Lambda trigger - Amazon Cognito

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-lambda-inbound-federation.html

やってみた

実際にフェデレーションLambdaトリガーを設定して動作を確認してみます。

前提

  • Cognitoユーザープールが作成済み
  • 外部IdP(今回はGoogle)との連携が設定済み
  • フェデレーショントリガー用のLambdaとして「inbound-federation-lambda」を作成、トリガーとして設定済み
  • Amplify.js(Reactアプリケーション)でマネージドログインを利用した認証を実装済み

CognitoとGoogleの認証連携の設定については、次のブログを参照してください。

https://dev.classmethod.jp/articles/amazon-cognito-google-cloud-oauth-2-0/
https://dev.classmethod.jp/articles/amazon-cognito-google-social-signin/

Amplify.jsでマネージドログインを利用した認証のサンプルについては、こちらのブログを参照してください。

https://dev.classmethod.jp/articles/learn-authentication-using-cognitos-hosted-ui-with-amplify-react/

1. Googleから連携される情報を確認する

フェデレーショントリガー用のLambdaとして、次のコードのLambdaをセットしておきます。
このLambdaは受け取ったデータをログに全部表示するだけで、受け取ったものをそのまま何も処理せず返しています。
これを使ってどんな形のデータが流れてくるか確認します。

  • 関数名:inbound-federation-lambda
  • ランタイム:Node.js 24.x
  • アーキテクチャ:arm64
index.js
exports.handler = async (event) => {
  console.log(JSON.stringify(event, null, 2));

  return event;
};

その後に、Reactアプリケーションを立ち上げて、マネージドログインページを開きます。

cognito1

Googleを外部IdPとして設定していると、マネージドログイン画面に「Sign in with Google」のボタンが追加されるので、クリックしてGoogleにログインします。

cognito2

Googleのログイン処理が終わると、Cognitoのマネージドログイン画面にリダイレクトされ、続けて自分のReactアプリケーションにリダイレクトされて処理が返ってきます。ここまでくれば、ログインは完了しています。

cognito3

このとき、トリガーで実行されたLambdaのCloudWatchLogsを見ると、ログを出力しており実行されていることが確認できます。

logs1

ログからIDトークンにどういう情報が入っているかわかったので、これをカスタマイズしてみましょう。

logs2

2. Googleから連携される情報をカスタマイズする

フェデレーションLambdaトリガーが受け取るパラメーターは、次のような形のJSONになっています。

JSONの全貌
{
    "version": "string",
    "triggerSource": "InboundFederation_ExternalProvider",
    "region": AWSRegion,
    "userPoolId": "string",
    "userName": "string",
    "callerContext": {
        "awsSdkVersion": "string",
        "clientId": "string"
    },
    "request": {
        "providerName": "string",
        "providerType": "string",
        "attributes": {
            "tokenResponse": {
                "access_token": "string",
                "token_type": "string",
                "expires_in": "string"
            },
            "idToken": {
                "sub": "string",
                "email": "string",
                "email_verified": "string"
            },
            "userInfo": {
                "email": "string",
                "given_name": "string",
                "family_name": "string"
            },
            "samlResponse": {
                "string": "string"
            }
        }
    },
    "response": {
        "userAttributesToMap": {
            "string": "string"
        }
    }
}

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-lambda-inbound-federation.html

このJSONの、 response.userAttributesToMap にデータを渡すことで、Cognito側にデータを受け渡すことができます。

重要な注意点として、 userAttributesToMap{}(空オブジェクト) だった場合は、デフォルト値がCognitoに渡されています。

カスタマイズする場合、このデフォルト値が渡されなくなります。そのため、明示的に必要な情報を含める必要があります。

例えば、Googleの属性マッピングとして以下のように設定していたとします。

ユーザープール属性 Google属性
email email
username sub

その場合、 userAttributesToMap にも、 emailsub の項目を次のような形で設定しておかないと、属性マッピングがうまくいきません。

{
  "userAttributesToMap": {
    "email": "<<何らかのE-mail>>",
    "sub": "<<何らかのsub的な文字列>>"
  }
}

最低限の情報として、このように設定します。

index.js
exports.handler = async (event) => {
    console.log(JSON.stringify(event, null, 2));
    const { providerType, attributes } = event.request;

+   event.response = {
+       userAttributesToMap: {
+           sub: attributes.idToken.sub,
+           email: attributes.idToken.email,
+       }
+   }

    return event;
}

今回は、これに追加してE-mailのドメイン部分だけ抽出して属性に追加してみます。

先ほどのコードに email_domain の属性を追加します。

index.js
exports.handler = async (event) => {
    console.log(JSON.stringify(event, null, 2));
    const { providerType, attributes } = event.request;

    event.response = {
        userAttributesToMap: {
            sub: attributes.idToken.sub,
            email: attributes.idToken.email,
+           email_domain: attributes.idToken.email.split("@")[1],
        }
    }

    return event;
}

Lambdaをデプロイした後、Cognitoの ソーシャルプロバイダーと外部プロバイダー > IDプロバイダー Google の属性マッピング の編集を開き、
ユーザープール属性に custom:mycustom1 というCognito側のカスタム属性、とGoogle属性にLambdaトリガーで追加した email_domain をそれぞれ追加します。

cognito4

これで、Cognitoのユーザープール属性 custom:mycustom1 に Lambdaトリガーで抽出したE-mailのドメイン名がマッピングされます。

この設定をした後、Googleログインしてみると、トリガーが動き、ユーザー属性に custom:mycustom1gmail.com とドメイン名が連携できることが確認できました。

cognito5

まとめ

フェデレーションLambdaトリガーを使うことで、外部IdPからの属性を柔軟にカスタマイズできるようになりました。

外部IdPと連携した情報を加工したい場合に役立ちそうです。

この記事をシェアする

FacebookHatena blogX

関連記事