Amazon Cognito のユーザー認証機能を使ってログイン機能を実装しているシステムで、連続で複数回ログインに失敗するとロックアウトが発生するが、単にログインに失敗しているだけなのか、ロックアウトが発生しているかが見分けがつかなかった。
そこで、今回はロックアウトを見分ける方法について調査結果を共有します。
結論
ログインに失敗した場合も、ロックアウトによる失敗もNotAuthorizedExceptionが発生するが、メッセージに違いがあるため、それを参照することで見分けることができる。
ログイン失敗の場合
Incorrect username or password.
ロックアウトによる失敗の場合
Password attempts exceeded
調査と検証
Cognitoでのイベント履歴はCloudTrailで確認することができる。
CloudTrail > イベント履歴でイベント名「InitiateAuth」でフィルタリングするとわかりやすい。
1つずつイベントの中身を確認したところ、最初にログインが失敗した時のログではエラー情報が下記のようになっていた。
しばらくは同じエラーが続いたが、あるタイミングから下記のようにerrorCodeは変わらないが、errorMessageに変化があっった。
このことから、例外の種類はNotAuthorizedExceptionで変わらないが、エラーメッセージを見れば見分けがつくということがわかった。
念の為、下記のコードで検証を行った。
try {
await cognito.initiateAuth(params);
} catch (error) {
if(error.name === 'NotAuthorizedException' && error.message === 'Password attempts exceeded'){
return {
code: 'ロックアウトされているよ';
};
}
return {
code: 'ロックアウト以外の理由で失敗しているよ';
}
}
その結果、複数回ログイン失敗を連続で行うと途中から返されるコードが'ロックアウトされているよ'に変化することが確認できた。
ロックアウトの仕様について
認証されていないか、または IAM 認証でのサインインに 5 回失敗すると、Amazon Cognito はユーザーを 1 秒間ロックアウトします。ロックアウトの期間は、試行が 1 回失敗するたびに 2 倍になり、最大で約 15 分になります。ロックアウト期間中に試行すると Password attempts exceeded 例外が生成され、その後のロックアウト期間の長さには影響しません。サインイン試行の累積失敗回数 n (Password attempts exceeded 例外を含まない) に対して、Amazon Cognito はユーザーを 2^(n-5) 秒間ロックアウトします。ロックアウトを n=0 初期状態にリセットするには、ユーザーは、ロックアウト期間後にサインインに成功するか、連続 15 分間、サインイン試行を開始してはなりません。この動作は変更される可能性があります。この動作は、パスワードベースの認証も実行しない限り、カスタムチャレンジに適用されません。
initiateAuthが出すエラー