ALB + Cognito 認証で 2要素認証を実現する

上記参考にしたサイト

Cognitoのセットアップ

ユーザープールの作成

ALBで参照する cognito の ユーザープールを作成する
ユーザープールリファレンス (AWS マネジメントコンソール)



初めてなので「ステップに従って設定する」を選択

Eメールアドレスでログインできるようにする

ログイン必須要素も同様
後で変更出来ないため注意し、よくわからない場合はトライアンドエラーをちゃんと行っておかないと

カスタム属性はスキップ

パスワード強度
デフォルトでは 7日間 アクティブでない場合失効してしまうため要件に応じて調整が必要そう

ユーザープール全体で MFA を有効化出来るかどうかは初期作成時のここでしか設定出来ない
MFA を使うかどうかはユーザー作成時に設定できるため、基本は有効化しておいたほうが無難そう

MFA で SMS をチェックした場合表示のように **重要: ユーザーに SMS メッセージを送信して電話番号の確認や MFA を行うには、Amazon SNS に対して使用量の上限の引き上げをリクエストする必要があります。**とでてくる
これは Amazon SNS で送る SMS のデフォルト上限利用金額が 最大 1$ になっているため
利用するなら 上限金額をあげておけよということらしい⇩

パスワード再発行時に利用するのは必須要素の Eメールにしておく

Cognito の SMS キック用ロールを作成

Eメールのカスタマイズ
選べるリージョンは「バージニア」「オレゴン」「アイルランド」
パスワード通知時に飛ぶメールなので特にカスタマイズしない

デフォルトは下記のようなメールで飛んでくる

件名:仮パスワード
From:no-reply@verificationemail.com
BODY:ユーザー名は hogehoge@mogemoge.com、仮パスワードは ####### です。

SESサービス経由でのメール送信を選べば From メールアドレスを指定できるらしい
今回はしない

ちなみにここでは出てこないが最後まで作成すると下記のようなメッセージが出てくる

注意: Cognito がお客様の代わりに E メールを送信することを選択しました。 ベストプラクティスは、毎日の E メールの制限から、本番ユーザープール用に Amazon SES を介してお客様が E メールを送信することです。

すでに SES を設定しているのであればそうした方がいいのかも知れない


メッセージのカスタマイズもしない

必要であれば

ユーザーとアクセス端末情報をトラッキングし、マッチング記録してよりセキュリティを高められますよとのこと
MFA を利用する場合端末指定で送ることもできるらしい
今回はスキップ

認証されたトークンを持つ端末からのみ Cognito の認証API をキックできるよう、端末を登録しますかとのこと
今回は ALB で連携するので後で作成する

認証フローの処理流に Lambda をキックしてより複雑な認証処理をカスタマイズできる
しない

最後に設定内容を確認し作成すると完了
作成後設定変更箇所があるためちゃんと確認しておく

クライアントアプリ設定

作成しただけではまだ使えない
作成したユーザープールを選択し、以下を変更する

後日談だが「時間ベースのワンタイムパスワード」にチェックを入れていると MFA が上手く動かず?
SMS 認証してないのにログイン出来てしまうことがあったためチェックを外しておく

ALB 用のアプリクライアントキーを作成
これでこのユーザープールは ALB からしかキックされない
名前は任意でいい

クライアントアプリ、今回の場合でいうと ALB の認証用設定を登録する
この辺は ALB + OIDC (Google認証) と同じ

Cognito の ユーザープール専用ドメインを作成する

ユーザーの作成

認証に使うユーザーを登録する

ユーザー名はメールアドレスと同じにしておく
電話番号は国際電話の記述に則って登録する必要がある
作成すると作成時に設定したメールの内容で仮パスワードのメールが飛んでくる
なおユーザー情報は作成後変更できないため間違えた場合は再作成する必要がある

電話番号を記述すれば MFS を利用できるし、空欄にすれば利用できない

ALB の設定

すでに作成済みの ALB に認証処理を追加

認証設定

例えば特定の IP からアクセスがあった場合のみ認証処理をするようにルールを追加する

認証処理で先程作成したユーザープール、アプリクライアントキーを選択する

認証確認

ブラウザでアクセスしてみる

認証画面が出てきて、メールアドレス、仮パスワードを入力するとパスワードの初期化が求められる

MFA 有効可していた場合ここで SMS に送られる認証用番号の入力が求められる
SMSは遅いときは数分位かかって飛んでくることもあった

2つの認証がクリアされるとサイトにアクセスすることが出来る

1回ログインすれば同一セッションでれば認証は1回だけで済む
こういう OpenAuth とかのセッション管理はどうなってるんだろ?Cookie?勉強しないとなぁ

ログイン状況の監査

Cognito のユーザープールをつかってアカウント管理、認証管理を行った場合監査情報はどこかに保持されるのか?

下記を読む限り、 Cognito に対する API コールや 設定変更については CloudTrail に残っていそうだが、 どのユーザーが、どの IP(端末)で 認証成功・失敗したかはわからないような気がする
AWS CloudTrail を使用した Amazon Cognito API 呼び出しのログ作成

試しに CLoudWatchLogs で連携している CloudTrail のログを cognito とかで大雑把に検索してもそれらしいのは出てこなかった
ここはもう少し調べる必要がありそう

もし詳細に認証情報を取得したい場合は ユーザープールのトリガー機能を利用して、Lambda と連携して作り込めば取れるかも知れない

またが 認証するユーザーが基本 MFA 認証を利用するのであれば、 Amazon SNS の SMS ログを CloudWatchLogs で連携すれば最低限誰がアクセスしたかはわかるか?
※認証に成功すれば Webアプリケーション側にログが残るし、失敗すれば ALB のログに残って3つのログを突き合わせればなんとかなりそう…?

SMS のログ出力設定

Amazon SNS から SMS を選択し、配送ステータスのログオプションを設定する
SMS 配信用の Amazon CloudWatch のメトリクスおよびログを表示する

「サンプルの成功率のデフォルト」 で、Amazon SNS が CloudWatch Logs でログに記録する正常な SMS 配信の割合を指定します。
たとえば、失敗した配信にのみログを書き込むには、この値を 0 に設定します。正常な配信の 10% に対してログを書き込むには、10 に設定します。
割合を指定しないなら、Amazon SNS は、すべての正常配信に対してログを書き込みます。

設定後、SNS を飛ばしてみると CloudWatch に下記のように出力されていた


※デフォルトで保持期間が 30日 になっていたので監査目的なら変更しておこう

{
    "notification": {
        "messageId": "**************************************",
        "timestamp": "2019-08-30 12:32:01.822"
    },
    "delivery": {
        "phoneCarrier": "SoftBank Mobile",
        "mnc": 20,
        "destination": "+8180********",
        "priceInUSD": 0.07148,
        "smsType": "Transactional",
        "mcc": 440,
        "providerResponse": "Message has been accepted by phone carrier",
        "dwellTimeMs": 351,
        "dwellTimeMsUntilDeviceAck": 3178
    },
    "status": "SUCCESS"
}

これならいつ、どの電話番号に SMS 認証コードを発行したかは確認できそうだ
ついでに 1回あたりの金額もわかるのか

あとは今回 ALB のロギングは有効化してなかったからわからないけど、
Cognito の認証失敗した場合 ALB のログに出るのか、出るなら 401 エラーとかなのか?
Application Load Balancer のアクセスログ

マニュアルを見る限りは少なくとも認証に成功したか、失敗したかはログに出そうな気がする
SMSのログと突き合わせれば いつ、どのアクセス元IPが、どの電話番号のユーザーで認証リクエストを出して、成功 OR 失敗 したかはわかりそう

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)
Share Comments
comments powered by Disqus