Amazon Cognito で複数の Idp を使って1人のユーザーを認証する
課題
例えば「Googleでサインイン」を併用している場合、
特に対策を行わない状態では、
同じメールアドレスでも Cognito UserPool のユーザーと Google のユーザーが別々に作成されます。
こんな時に、
同じメールアドレスのユーザーが統合され、
1人のユーザーが複数の認証方法を使ってサインイン出来るようにする方法についてメモします。
解決方法
AdminLinkProviderForUser という API を使用します。
AdminLinkProviderForUser - Amazon Cognito
例えば、Cognito Idp のユーザーに対して Google サインインを行えるようにする場合は次のコマンドを実行します。
$ aws cognito-idp admin-link-provider-for-user --user-pool-id <user_pool_id> \ --destination-user ProviderName=Cognito,ProviderAttributeValue=<destination_username> \ --source-user ProviderName=Google,ProviderAttributeName=Cognito_Subject,ProviderAttributeValue=<source_username>
ここで、
<destination_username>
は Cognito Idp のユーザー名です。
<source_username>
は Google Idp のユーザーIDです。
(「Googleでサインイン」で作成されたユーザーの identities.userId
の文字列)
ただし、SourceUser がサインアップ済みの場合は次のようなエラーとなります。
An error occurred (InvalidParameterException) when calling the AdminLinkProviderForUser operation: Merging is not currently supported, provide a SourceUser that has not been signed up in order to link
サインアップ済みの場合は一度ユーザーを削除してから行いましょう。
また、サインアップの際に Pre-SignUp Lambda トリガーを使うというのも良さそうです。
実行すると、ID フェデレーションのための情報が Cognito Idp のユーザーに保存されます。
サインインを行ってみると、JWT トークンも同じ sub を示していました。
ユーザー名/パスワード でサインインした時
{ "sub": "d820495d-a735-4cce-9c2f-0dda2e8588b0", "event_id": "5a6e54c6-b4b7-4075-8f0e-614ed087b0d2", "token_use": "access", "scope": "openid profile", "auth_time": 1624118692, "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/xxxxxxxxxx", "exp": 1624118992, "iat": 1624118692, "version": 2, "jti": "31c48041-9302-44a4-aac6-206a7a63faba", "client_id": "xxxxxxxxxx", "username": "d820495d-a735-4cce-9c2f-0dda2e8588b0" }
Google でサインインした時
{ "sub": "d820495d-a735-4cce-9c2f-0dda2e8588b0", "token_use": "access", "scope": "openid profile", "auth_time": 1624119112, "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/xxxxxxxxxx", "exp": 1624119412, "iat": 1624119112, "version": 2, "jti": "cbc8e873-184b-45ca-a7d8-f2a21f1cdfc8", "client_id": "xxxxxxxxxx", "username": "d820495d-a735-4cce-9c2f-0dda2e8588b0" }
(余談)
ユーザー名/パスワード でサインインした方は、
なぜか event_id
というクレームが増えてました。