IE課で研修中の前田(青)です。
業務中、フルーツグラノーラをつまんでいたら食べ過ぎてしまったため運動しなければと焦っています。
今回は、前回の記事の執筆中に見つけたALBの認証アクションを実際に試してみたいと思います。
ALBの認証アクションとは?
ALBのリスナーでHTTPSを選択すると「認証」というアクションを有効化できます。 認証方法にはOIDC (OpenID Connect)と、Amazon Cognitoがあります。お手軽さ重視ということで今回はCognitoを選択し、実際に認証をやってみたいと思います。
検証環境の説明
下記のような環境で検証を行います。 認証アクションはリッスンするプロトコルにHTTPSを使用している場合のみ有効にできるため、ALBにはACMから発行した証明書を設定しておきます。
Cognito認証の設定手順
Cognitoのユーザープールを作成する
サインインエクスペリエンスを設定
サインインオプションにはユーザ名を指定します。
セキュリティ要件を設定
今回はお試しなのでMFA認証はなしにしておき、その他の項目はデフォルトのまま次へ進みます。
サインアップエクスペリエンスを設定
デフォルトのまま次へ進みます。
メッセージ配信を設定
今回は「CognitoでEメールを送信」にしておきます。 このオプションは1日で最大50通しか送れないため、本番環境では「Amazon SESでメール送信」を選択した方がよいでしょう。
アプリケーションを統合
「Cognito のホストされた UI を使用」にチェックを入れることで、Cognitoが用意した認証画面を使用できます。
認証画面のドメインを設定します。本番稼働ではカスタムドメインが推奨されますが、今回はCognitoドメインを指定します。 Cognitoドメインは下記画像のように「使用可能」となるならばどんな文字列を設定しても大丈夫です。
アプリケーションクライアントとは、ALBがCognitoと連携するために必要な設定です。下記を設定します。
アプリケーションタイプ…秘密クライアント
クライアントのシークレット…生成する
コールバックURL…https://XXXX/oauth2/idpresponse(XXXXには、ALBのDNS名もしくは、ALBのDNS名と紐づくカスタムドメインが入ります。)
「高度なアプリケーションクライアントの設定」「属性の読み取りおよび書き込み許可」はデフォルト設定のまま次へ進みます。
確認及び生成
問題なければ一番下の「作成」ボタンを押下します。
ユーザープールが作成されました!
ユーザープールにユーザーを作成する
ユーザープールの詳細画面から「ユーザーの作成」ボタンを押下します。
ユーザー名、パスワードを設定して「ユーザーを作成」ボタンを押下します。
ユーザーが作成されました!
ALBで認証アクションを設定する
ALBのHTTPSリスナーを選択し、「リスナーの編集」ボタンを押下します。
「アクションの追加」ボタンを押下し、「認証」ボタンを押下します。
認証アクションにおいて下記を設定します。
Identity provider…Amazon Cognito
Cognitoユーザープール…作成したCognitoユーザープール
アプリケーションクライアント…作成したアプリケーションクライアント
詳細設定はデフォルトのままでOKです。設定したら一番下の「変更内容を保存」ボタンを押下します。
認証アクションが追加されました!
アクセスしてみる
それでは実際にアクセスしてみましょう。 ALBに紐づけたカスタムドメインにhttpsでアクセスします。
Cognitoによってホストされた認証画面にリダイレクトされました。
先ほど作成したユーザ名を入力してサインインします。
パスワードを変更します。
無事にサインインに成功し、画面が表示されました!
補足1_認証の詳細について
今回設定したCognitoの認証は「Authorization Code Grant(認可コード許可)」というものです。 認可コード許可の詳細についてはOAuth2.0の認証フローや、CognitoのBlackbelt資料のP42~が分かりやすいです。上に載せた検証環境の図では簡略化していましたが、クライアント-ALB-Cognito間の認証の正確な流れは下図のようになります。
補足2_CloudFrontをALB前段に置く場合
認証アクションを有効にしているALB前段にCloudFrontを置く構成は可能ですが、クライアントからのアクセスをCloudFront経由のみに制限することは出来なさそうです。
コールバックURLにはALBのDNS名もしくは、ALBのDNS名と紐づくカスタムドメインを設定する必要があり、クライアントからALBへの直接アクセスが発生するためです。
もしCloudFront経由のみに制限したい場合はLambda@Edgeを使用してCloudFrontへアクセスする前に認証を行うなどの方法をとりましょう。
一応、下記にざっくりと設定ポイントを記載しておきます。
CloudFrontディストリビューション-ALB間の通信のHTTPS化
CloudFront-ALB間の通信をHTTPS化します。手順の詳細については下記ブログをご覧ください。 blog.serverworks.co.jp
CloudFrontからのHTTPS通信をALBセキュリティグループで許可
ALBのセキュリティグループにて、CloudFrontのマネージドプレフィックスリストからのHTTPS通信を許可します。
CloudFrontのキャッシュポリシー設定
Application Load Balancer を使用してユーザーを認証する - Elastic Load Balancingには、認証アクションを追加しているALB前段へCloudFrontを配置する場合の推奨設定が記載されています。
Application Load Balancer の前面で CloudFront ディストリビューションを使用している場合は、次の設定を有効にします。
・転送リクエストヘッダー (すべて) — CloudFront が認証されたリクエストに対する応答をキャッシュしないようにします。これにより、認証セッションが期限切れになった後にキャッシュから処理されるのを防ぎます。または、キャッシュが有効になっている間にこのリスクを軽減するために、CloudFront ディストリビューションの所有者は、認証 Cookie が期限切れになる前に有効期限 (TTL) の値を期限切れに設定することができます。
・クエリ文字列の転送とキャッシュ (すべて) — ロードバランサーが、IdP を使用してユーザーを認証するために必要なクエリ文字列パラメータにアクセスできるようにします。
・Cookie 転送 (すべて) — CloudFront がすべての認証 Cookie をロードバランサーに転送するようにします。
上記設定を実現するため、下記のキャッシュポリシーを作成し、CloudFrontディストリビューションに設定しておきます。
アクセスしてみる
CloudFrontに紐づけているカスタムドメインにHTTPSリクエストを送信します。
ユーザ名、パスワードを入力します。
サインイン出来ました!
尚この時、ALBに紐づくカスタムドメインにリダイレクトされていますね。
感想
ALB + Cognitoの認証アクションは結構簡単に実装することが出来ました。
しかしその裏では補足1に書いたようなリダイレクトが発生しており、Blackbelt資料やブラウザの検証ツールとにらめっこして把握するのに苦労しました。
ネットワークや認証認可周りにもっと強くなる必要があると感じたので、精進していきたいです。
この記事がどなたかの一助になれば幸いです。