📑

Amazon Cognitoの複数MFA設定について

2024/11/09に公開

はじめに

Amazon CognitoユーザプールがサポートするMFAはEメール、SMS、およびTOTPソフトウェアトークン(Authenticatore)の3種類があります。
このMFAを組み合わせてしようする場合、どのような仕様なのか調査してみました。

結論

ユーザプールでメールMFAを有効にしていると、デフォルトでメールMFAが優先されるようです。
ただし、SMSとTOTPで利用するMFA設定や優先度設定をしていないと動作しないケースがあるため、デフォルト設定ではなく利用するMFAや優先度は明示的に設定した方が良いようです。

ユーザMFAの設定

ユーザMFAを利用するには以下の3ステップが必要になります。

  1. ユーザプールのMFAを有効化
  2. ユーザMFAを有効化
  3. ユーザMFAを設定

ユーザプールのMFAを有効化

MFAを利用するには、ユーザプールでMFAを有効にする必要があります。利用したいMFA種別は全て有効化しておく必要があります。
Amazon Cognito>User pools>user pool id>Editで編集画面に遷移します。

なお、ユーザプールのMFAを無効化すると、ユーザのMFA設定は全て無効化されるようです。

次に編集画面では利用したいMFAにチェック入れて、ユーザプールでMFAを有効化していきます。
TOTPは前提条件なしで有効化できますが、SMSとEメールは前提条件が整っていないと有効化できません。
ただ、インフォメーションで表示されているリンクを辿っていけば設定できるようになっていました。
まずはConfigure SMSでSMS設定を有効化します。

ここではIAM role名を設定して保存するだけで権限が付与されました。

ただ、SMSはSNSを使って送られますがsandboxの場合、特定の検証済み電話番号にのみSMS送信できるよう制限されているので、事前に電話番号を登録しておくと良いかと思います。

次に先ほどのEdit multi-factor authentication (MFA)画面のインフォメーションからadvanced security featuresに遷移してactivate advanced security featuresを有効化します。

Add an email option to MFAを押下してEメールのMFAを有効化します。

またEdit multi-factor authentication (MFA)画面のインフォメーションからsend email with Amazon SESに遷移してEメールの設定を有効化します。

今回私はSESを使ってメール送信することにしました。
SESを選択する場合、FROM email addressにはSESで利用するメールドメインを選択するようになっており、実際にメール送信するアドレスはFROM sender name - optionに入力する必要があります。

FROM sender name - optionを入力せずに進むと"InvalidParameter Exception"で失敗し、メールアドレスのARNが取得できない旨のエラーが出るようです。

またEdit multi-factor authentication (MFA)画面のインフォメーションからaccount recovery設定画面に遷移してリカバリーオプションを変更します。
デフォルトのEmail onlyだとダメらしいのでSMSでも送れるよう複数パスを持つよう選択します。

またEdit multi-factor authentication (MFA)画面に遷移すると全てのインフォメーションが消えて全てのMFAが有効化できるはず。

ユーザMFAを有効化

ユーザプールが有効になったらユーザごとにMFA設定しなくてもMFAは要求されるようになります。
複数のMFAがある場合、どのMFAを使うのかユーザごとに設定することも可能です。

MFA設定組み合わせ時の動作について検証

MFAで利用可能なユーザ属性が複数設定されている場合の動作が直感的に理解できなかったので、ユーザプールの設定と組み合わせどのような挙動になるか検証したいと思います。

全てのも有効にすると、デフォルトのMFAがメールになる挙動でした。
これは電話番号を設定しても、ユーザ詳細画面のMFA MethodSMSであっても挙動としてはメールMFAが優先されていました。

明示的にユーザのMFA設定で有効にするMFAを設定したり優先度を設定することで意図したMFAが採用されるようです。

ユーザプール:メール ユーザプール:SMS ユーザプールTOTP ユーザ属性:メール ユーザ属性:電話番号 ユーザMFA設定:メール ユーザMFA設定:SMS Preferred MFA method MFA
ON ON ON あり なし OFF OFF - メール
ON ON ON あり なし ON OFF - メール
ON ON ON あり なし OFF ON - -
ON ON ON あり あり ON OFF - -(※1)
ON ON ON あり あり OFF ON - メール
ON ON ON あり あり ON ON メール メール
ON ON ON あり あり ON ON SMS SMS

※1: ユーザプールでSMS ONかつユーザに電話番号が設定されていると、SMS MFAはデフォルト有効になるため、この組み合わせは仕様上あり得ません

Amazon CognitoのDeveloper Guideでもメールが優先されると記載されているのでこれが仕様らしいです。

次はSMSとTOTPの優先度について調査しました。

ユーザプール:メール ユーザプール:SMS ユーザプールTOTP ユーザ属性:メール ユーザ属性:電話番号 ユーザ属性:TOTP ユーザMFA設定:SMS ユーザMFA設定:TOTP Preferred MFA method MFA
OFF ON ON あり なし あり OFF OFF - TOTP
OFF ON ON あり あり あり OFF OFF - -(NG)
OFF ON ON あり あり あり ON OFF - SMS
OFF ON ON あり あり あり OFF ON TOTP TOTP
OFF ON ON あり あり あり ON ON SMS SMS

どちらも設定されているとデフォルトで有効になっているはずのSMS認証が有効になると思っていたが、実際にはどちらも動作せずログインできませんでした。
これはTOTPを一度有効にした後に電話番号だけ設定した状態だったためテストしたユーザで電話番号検証できていなかったからかもしれないと推測してphone_verifiedフラグは有効にしましたが結果は変わらずでした。
当該ユーザでMFA設定を一度開いて更新したら普通に動作したので、必ずどのMFAを使うのか設定しないと挙動は不定なのかもしれません。

おわりに

私のドキュメントの読み込みが甘いのかもしれませんが、Amazon CognitoのMFA設定はデフォルトの挙動が怪しく、将来的にWebAuthnなどMFA種別がさらに追加になった時、挙動が変わってしまったり動作しなくなる可能性があると思いました。
なので、デフォルト動作に依存せず、必ずMFA設定で有効にするMFAと優先するMFAは設定するよう実装した方がいいと思います。

GitHubで編集を提案

Discussion