Cognito の Managed Login で Email の MFA を有効化する

# はじめに

Cognito の Managed Login が追加され、リッチな認証画面が提供されました。ALB と Cognito を連携することで、比較的簡単に認証機能を追加できるうれしさがあります。セキュリティをより高めるために、Cognito の MFA を利用したくなります。

今回の記事では、Cognito の MFA として Email を利用したときの Managed Login の利用方法を確認してみようと思います。



# User Pool

適当に User Pool を作成します。

![image-20250222180643644.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/552e6a64-558c-440e-96e4-21169662e4a2.png)



Create

![image-20250222180737000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/f079528d-3476-4131-a001-f25542a2c0b1.png)



# SES の連携設定

Cognito の MFA を Email にするときに、SES との連携設定が必要です。Edit を押します。

![image-20250222213228506.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/822b0d1d-7694-4aef-9b14-18a28ffece1f.png)



この記事の手順では、事前に SES でドメイン `sugiaws.tokyo` を登録しており、これを利用します。

FROM sender name は `表示名 <送信元メールアドレス>` の形式で指定すると良いです。

![image-20250222213343349.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c4948c01-373b-482d-8ed0-e0c27de01e6c.png)





# MFA を有効化

MFA を有効化します。

![image-20250222180847424.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/7707ec0e-e930-49d9-a5c4-efbd7f42b7ea.png)



User Pool の単位では、Optional MFA として、 Email message を有効化します。

この画面で指定する User Pool の Optional MFA の意味は、User Pool の中で MFA を利用するユーザーと利用しないユーザーの混在を許すという意味です。「MFA を必須にしたいんだ」ということを考えると思うのですが、その場合は、Optional MFA を選択したうえで、MFA を必須にしたいユーザー単位で MFA を有効化すれば大丈夫です。

![image-20250222225518847.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/038cc7a2-45ea-4a7f-bbfc-45dddc0e6b19.png)



# Callback

Cognito と連携する Web アプリケーションの Callback URL を設定します。

![image-20250222182553937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/1c32811b-bdd6-4a8d-a0c7-701be3312a81.png)



こんな感じに、Web アプリケーションの ドメイン名の末尾に、`/oauth2/idpresponse` を追記した URL を設定します。これは、ALB と Cognito の連携で必要な設定です。

https://coginito-mfa-test01.sugiaws.tokyo/oauth2/idpresponse

![image-20250222182650190.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/cacfd1ab-6c08-4a92-9d35-eda052e991e7.png)



# ALB と Cognito を紐づける

ALB の HTTPS Listener を Cognito と紐づけます。

![image-20250222182149093.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/8607322d-cd24-4de3-95bf-31f17e1a7abf.png)



上の手順で作成した Cognito Userpool を選択します。

![image-20250222182422969.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/5b5ca9c5-99ec-49b6-832c-6b13a340608e.png)



# Self sign-up の停止

Self sign-up は停止します。

![image-20250222182751921.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/1e109b8a-ef5c-46b9-8de7-a444edd85d79.png)



チェックを外します。

![image-20250222182759489.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0fd59995-564d-4d8f-983c-4faa726ee8dd.png)

# 招待メールを設定

ユーザーの招待メールを、わかりやすく日本語で送信できます。

![image-20250222183206390.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/8c880a4e-6531-4e67-a7a7-b5524e727b10.png)



こんな感じのメッセージをテンプレートとして登録できます。

```
{username} に一時パスワードを送付します。<br>
一時パスワード :  {####} <br>

以下のサイトにアクセスしてください <br>
https://coginito-mfa-test01.sugiaws.tokyo/
```



![image-20250222183308680.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/72708831-fe4f-4c65-b560-12fd50bf4d40.png)



# 管理者が招待

では、管理者としてユーザーを招待してみましょう。Create user を押します。

![image-20250222182833633.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a645c5c6-49cc-429b-955d-bffee8f07377.png)



メールアドレスを入れて、Create User を押します。

![image-20250222182923473.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d5bb9505-0cc4-432e-91ac-d260c470bc9b.png)



作成したユーザーは MFA は無効化されているので、有効化をします。ユーザーの詳細画面を開きます。

![image-20250222230559276.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0f298d08-e472-4d56-bb5f-0cc421c37e4e.png)





Update MFA configuration を押します。

![image-20250222230624133.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/33271fb0-c33a-4119-9a52-bb5138302925.png)



Email の MFA を有効化します。

![image-20250222230643504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ba13f60b-d3a4-4144-ae0c-a162840eb6d3.png)

# ユーザーに届くメール

ユーザーのメールアドレスに次のようなメールが届きます。

![image-20250222183543803.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d696b0cc-9d0a-4965-9e3a-7e367a00e54d.png)



ログインします。

![image-20250222183606762.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0984c7ca-d731-4302-862e-4c9a00fe68cf.png)



パスワードを入れます。

![image-20250222183623237.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ec37db5e-9b44-42d9-af81-74a9c81a7700.png)



パスワードを変更します。

![image-20250222183636933.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e9cbe756-b145-453d-8ad3-71cd784bbd96.png)



メールに MFA としてのコードが送られます。

![image-20250222215029803.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2fbaae8b-8168-472f-942e-47c618e9f9bd.png)



こんな感じのメールが届きます。

![image-20250222215055691.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d05c3bea-63d3-49e8-9b10-936835e3799a.png)





コードを入れます。

![image-20250222215111401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2c4f99d8-f1c2-44e2-b487-5abb9496684a.png)



ログインできました。

![image-20250222215124697.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b9240cf6-230f-4b63-a5de-470da4d9cefd.png)





# パスワードを忘れたとき

この手順では、Managed Login 上のセルフサービスのパスワードをリセットする機能の「パスワードをお忘れですか？」は動作しません。

![image-20250222231556973.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/40ea2e0e-c69c-4758-88c1-b2d587cfd925.png)



Email を利用した MFA の場合、パスワードリセットの手法を Email にはできない仕様の制限事項があるためです。

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-settings-mfa.html

> ユーザーは、同じ E メールアドレスまたは電話番号で MFA とパスワードのリセットコードを受け取ることはできません。MFA の E メールメッセージからワンタイムパスワード (OTPs) を使用する場合は、アカウントの復旧に SMS メッセージを使用する必要があります。



Email の MFA を利用する場合は、SMS が利用できるように、UserPool の必須属性に電話番号を入れておくと良いと思います。



ただ、電話番号を利用していない場合は、別の手法でパスワードをリセットできます。管理者側で作業を行います。リセットしたいユーザーを選択します。

![image-20250222231836000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/65c29ce0-f17b-4199-b636-5f257f43ea07.png)



Update MFA configuration を押します。

![image-20250222231900203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/63a3ed64-3fef-4f1d-8996-8ab3314ee4f7.png)



一時的に MFA を無効化します。

![image-20250222231929609.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ea9e53ac-f001-42d0-bedd-c4eceb2251aa.png)

これで、ユーザー側のセルフサービスでパスワードのリセットが可能です。Managed Login の画面で「パスワードをお忘れですか？」を選択します。

![image-20250222232324795.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/bb0a2c38-753a-4389-9ffc-db046574761a.png)



コードが送られます。

![image-20250222232334513.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b328f49e-6fe5-4406-a2db-3f60eda12805.png)



コードが送られます。

![image-20250222232349501.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/3d8bed89-10f2-4b7f-9e0b-ea913fb7b233.png)



コードを入れてパスワードをリセットします。

![image-20250222232407666.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/fdbc583f-afee-4918-9cb4-497e75ae4245.png)



これでパスワードがリセットされログインができるようになります。

なお、このままでは MFA が無効化されているので、例えば、1 日後に管理者が MFA で Email を有効化すると良いでしょう。(もしかしたら、Lambda 連携でリセット後に MFA 自動有効化が出来るかも)





# 検証を通じてわかったこと

- Cognito の MFA には、Email、TOTP (Time-based One-time Password)、SMS の 3 種類が選択できる

- TOTP の選択肢は、MFA のデバイスを紛失したときの MFA リセットが直接的には出来なさそうだった。

  - [こちらの記事](https://repost.aws/questions/QU-pFnMqBOR06qDIpIF5wFsA/aws-cognito-reset-mfa-device) では、MFA の選択肢として SMS を利用できるようにしたうえで、TOTP の Device を紛失したときに、一時的に SMS に切り替えたうえで、Access Token を基に再度 TOTP Device を登録する手順が説明されている。
  - [また別の記事](https://medium.com/@alexkhalilov/how-to-reset-aws-cognito-lost-totp-c08c36892a6c) では、Cognito User Pool の MFA 設定を Require (必須) ではなく、Option にすることで、管理者側がユーザーの Access Token を取得する手順が説明されている。しかし、Option にすると、Managed Login でユーザーがサインアップする際に、MFA デバイスの登録画面が出てこなくて、独自の Web アプリケーション側で TOTP 登録画面を提供する必要があり、少し面倒。
  - このことを踏まえると、Email を利用した MFA では、デバイスを紛失する心配がなくなりよさそうに思う。登録したメールアドレスが利用できなくなってしまう場合が考えられるが、社内でユースケースではメールアドレスの紛失は基本考えなくてよいと思う。

- Email を利用した MFA の場合、パスワードリセットの手法を Email にはできない仕様の制限事項がある。Email の MFA を利用する場合は、SMS が利用できるように、UserPool の必須属性に電話番号を入れておくと良いと思う。(この記事の手順ではやってないけど)

  - https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-settings-mfa.html

  - > ユーザーは、同じ E メールアドレスまたは電話番号で MFA とパスワードのリセットコードを受け取ることはできません。MFA の E メールメッセージからワンタイムパスワード (OTPs) を使用する場合は、アカウントの復旧に SMS メッセージを使用する必要があります。