Cognitoの認証設計では、求める操作フローが標準仕様に収まるか、アプリ側で何を補う必要があるかを確認しておきたいところです。
無操作ログアウト、再認証、パスワード再設定など、6つの要件について結論と対応方法をまとめます。対象は、独自の画面からCognitoユーザープールのAPIを利用するWebアプリケーションです。
6つの要件と対応方法
各要件の結論は次のとおりです。仕様の根拠と追加実装の条件は、同じ番号の章に記載しています。
| 要件 | 結論 | 対応方法 |
|---|---|---|
| 1. 無操作ログアウト・即時失効 | トークンの有効期限・失効操作だけでは満たせない | アプリで操作時刻・失効状態を管理し、業務APIで拒否する |
| 2. 画面ロック・作業保持 | アプリ側の実装が必要 | ロック状態と作業データを管理し、解除時の本人認証にCognitoを使う |
| 3. SMSなしのパスワード再確認 | SMS MFAに進む標準フローではSMSが送られる | 再認証方式を見直すか、配送制御を追加する |
| 4. 再設定コードだけの事前検証 | 標準APIではコードと新パスワードが両方必要 | 最終送信時に検証する。事前検証が必須なら別フローを設計する |
| 5. ユーザー名の入力・保存情報なしでパスキー認証 | 標準の認証開始APIにはUSERNAMEが必須 |
保存情報があれば入力を省略できるが、APIへの指定は省略できない |
| 6. パスキー認証後、旧パスワードなしで変更 | 設定済みユーザーはChangePasswordで旧パスワードが必要 |
管理APIを使う場合は、本人確認・操作認可をアプリで実装する |
利用できる認証方式や組み合わせは、機能プラン・MFA・アプリクライアントの設定によって異なります。以下はCognito標準の認証フローを前提とし、外部IDプロバイダーや独自WebAuthn実装は扱いません。
AWS公式:認証フロー
1. 無操作ログアウト・即時失効
無操作期限と失効状態は、アプリ側で管理し、保護対象のAPIで確認します。
無操作期限は「最後の操作から何分経ったか」で判定します。JWTの有効期限を短くしても、同じ動作にはなりません。期限の判定はサーバー側で行います。
OWASP:アイドルタイムアウト
また、Cognitoでトークンを失効させても、JWTの署名・有効期限だけを検証するAPIでは、その失効を検出できません。失効後のアクセスを止めるには、API側でも拒否する仕組みが必要です。
AWS公式:トークンの失効
例えば、サーバーセッションに最終操作時刻・期限・失効状態を持たせ、業務処理の前に確認します。定期ポーリングを「操作」に含めるか、認可結果のキャッシュによって拒否が遅れないかも、この構成で確認する点です。
2. 画面ロック・作業保持
ロックと作業保持はアプリで実装し、解除時の本人認証にCognitoを使います。
画面を隠すだけではAPIの直接呼び出しを防げないため、サーバー側でもロック状態を確認して業務APIを拒否します。入力中のデータの保存・復元も、Cognitoの認証とは別の処理です。
OWASP:リクエストごとの認可チェック
解除時には、再認証したユーザーが元のセッションのユーザーと一致することと、セッションが有効なことを確認します。期限切れ・失効済みなら、古いセッションを復活させず、再ログイン後に作業を復元する構成にします。
作業データには、保存先・保持期間・復元できるユーザーを別途定めます。作業を残すために、セッションの期限まで延ばす必要はありません。
3. SMSなしのパスワード再確認
パスワード確認後にSMS_MFAへ進む標準フローでは、SMSが送信されます。
AdminInitiateAuthはパスワード照合専用のAPIではありません。コード入力画面を表示しないだけでは、SMS送信を止められません。
AWS公式:AdminInitiateAuth
SMS MFAの認証手順
配送を制御する方法にCustom SMS senderがあります。ただし、設定するとユーザープールのすべてのSMSをLambdaで処理するため、通常ログインや登録確認、パスワード再設定の配送も管理対象になります。
AWS公式:Custom SMS sender
AdminInitiateAuthのClientMetadataはこのトリガーに渡されません。「再確認用」というフラグを付けるだけでは、用途別に配送を切り替えられない点にも注意が必要です。
AWS公式:ClientMetadata
SMSの配送を抑えても、MFAが完了したことにはなりません。対象操作にパスワード確認だけで十分かを決めたうえで、再認証方式の変更か、配送制御の追加かを選びます。
4. パスワード再設定コードの事前検証
Cognitoの標準フローでは、再設定コードだけを先に検証できません。 ConfirmForgotPasswordには、確認コードと新パスワードの両方が必要です。
AWS公式:ConfirmForgotPassword
画面を分けることはできます。ForgotPasswordでコードを送った後、コードを保持して次の画面へ進み、新パスワードと一緒に送信する流れです。
この場合、コードの誤りがわかるのは最後の送信時です。「コードが正しいことを確認してから次の画面へ進む」という要件には、そのままでは対応できません。
事前検証が必須なら、アプリ独自のOTP(ワンタイムコード)で本人確認し、成功後にサーバーからAdminSetUserPasswordをPermanent: trueで呼ぶ別フローが考えられます。Cognitoの再設定コードを単独検証する方法ではありません。
AWS公式:AdminSetUserPassword
独自OTPでは、安全な生成・保存、有効期限、試行制限、一回限りの使用、検証結果と変更対象の結び付けをアプリで実装します。アカウントの存在を推測させない応答、変更通知、既存セッションの扱いも必要です。
OWASP:パスワード再設定
5. ユーザー名なしのパスキー認証
Cognito標準のUSER_AUTHフローでは、パスキー認証でもUSERNAMEが必要です。
AWS公式:InitiateAuth
画面での入力を省けるかは、サインインに使うユーザー名やメールアドレスをアプリが取得できるかで変わります。
| ユーザー名などの取得方法 | 画面での入力 | APIへのUSERNAME指定 |
|---|---|---|
| Cookieなどの保存情報から取得できる | 省略できる | 必要。保存値を渡す |
| 取得できず、利用者に入力してもらう | 必要 | 必要。入力値を渡す |
これはパスキー一般ではなく、Cognito標準フローの制約です。
6. パスキー認証後のパスワード変更
パスワード設定済みのユーザーは、パスキーで再認証してもChangePasswordで旧パスワードを省略できません。
AWS公式:ChangePassword
旧パスワードの要否は、ユーザーの状態と利用するAPIで変わります。
| ユーザーの状態・利用API | 旧パスワード | 呼び出しの認可 |
|---|---|---|
パスワード設定済みでChangePassword
|
必要 | 本人のアクセストークン |
パスワード未設定・パスワードレス認証のみでChangePassword
|
省略可能 | 本人のアクセストークン |
サーバーからAdminSetUserPassword
|
不要 | IAM権限。利用者の操作認可はアプリ側 |
ChangePasswordのアクセストークンにはaws.cognito.signin.user.adminスコープが必要です。旧パスワードなしで確定変更する構成では、サーバーからAdminSetUserPasswordをPermanent: trueで呼びます。
AWS公式:ChangePassword
AdminSetUserPassword
管理APIを呼ぶ前に、直近のパスキー認証の成功をサーバーで確認し、現在のセッション・変更対象のユーザー・パスワード変更操作に結び付けます。検証結果には有効期限を設け、使い回しを防ぎます。
OWASP:重要な操作での再認証
クライアントが送る「認証済み」フラグや変更対象のユーザー名だけを信頼して、管理APIを呼んではいけません。IAMが許可するのは管理APIの実行であり、利用者が誰のパスワードを変更してよいかはアプリで判断します。
OWASP:認可
まとめ
今回の6点は、アプリ側で状態を管理する要件と、Cognitoの入力項目・認証フローに制約がある要件に分かれます。
要件が標準仕様に合わない場合は、画面・操作フローを調整するか、追加実装で補うかの判断が必要です。例えば、再設定コードの検証を最終送信時にまとめられれば、事前検証用の独自OTPは不要です。
採用前に通常ログインだけでなく、ロック解除・再認証・パスワード再設定まで確認すると、追加実装の範囲を見積もれます。その実装・運用負担も含めて、Cognitoを使うか、別の認証サービスを選ぶかを比較したいところです。