Amazon Cognitoで構築するスケーラブルなWeb アプリケーション② - ALBにAmazon Cognitoによる認証機能を追加する

記事タイトルとURLをコピーする

こんにちは。
アプリケーションサービス部、DevOps担当の兼安です。

本記事はこちらの記事の続きです。

blog.serverworks.co.jp

今回はWebアプリケーションにAmazon Cognitoによる認証機能を追加する方法を説明します。

本記事のターゲット

Webアプリケーションの開発経験があり、今後、Webアプリケーションをスケーラブルにしたい方を対象としています。
記事中にロードバランサー(=ALB)やAmazon EC2などが出てきますが、これらの説明は割愛していますので、AWSのコンピューティングサービスやデータベースサービスの知識があることが前提となります。

今回の題材

今回は、MPA(Multi Page Application)のWebアプリケーションを題材にしてAmazon Cognitoの導入方法を説明します。
以下の構成図のように、MPAのWebアプリケーション自体はAmazon EC2で構築し、前段にALBを配置して、負荷分散を行っているとします。

ALB+Amazon EC2によるWebアプリケーションの構成図

この時、ALBにAmazon Cognitoによる認証設定を行うことで、Webアプリケーションに認証機能を追加することができます。

ALBにAmazon Congnitoによる認証を追加した構成図

認証・認可とAmazon Cognitoのユーザープールとアイデンティティプール

Amazon Cognitoには、大きく分けてユーザープールとアイデンティティプール(=IDプール)の2つの機能があります。
Cognitoによる認証設定を行う場合、ユーザープールを利用します。
アイデンティティプールは必ずしも必要ではありません。
個人的にこの2つはわかりにくいと感じるので、設定方法を説明する前に、この2つの違いを説明させていただきます。

まず、ユーザープールとアイデンティティプールは、Amazon Cognitoの中で認証・認可を行うための機能です。
認証・認可の違いを表にすると、以下のようになります。

項目 認証 (Authentication) 認可 (Authorization)
目的 本人確認 権限・アクセス制御
質問例 あなたは誰? あなたは何ができる?
入場口でスタッフが名簿と照合する  入場後、申し込み内容に応じてカードを渡される(一般 / VIP / スタッフなど)
Amazon Cognitoの機能 ユーザープール アイデンティティプール(IDプール)
AWSにおける役割 ユーザー情報の管理とログイン ユーザーとAWSリソースへのアクセス権(IAMロール)の管理と紐付け

ユーザープールは、ユーザー情報の管理とログイン機能を提供します。
ログイン画面も提供しており、認証全般を担当しています。

一方、アイデンティティプールは、ログインユーザーと事前に用意しておいたAWSリソースへのアクセス権(IAMロール)の管理と紐付けを行います。
アイデンティティプールのアイデンティティとは、自分らしさ個性を意味します。
役割と考えると分かりやすいかもしれません。
ユーザーに、どのような役割を紐づけるかを管理するのがアイデンティティプールです。
IDプールと略してしまうと、ユーザーIDと混同しやすくわかりにくくなってしまいますね。
アイデンティティプールは、端的に言うと、いわゆる権限管理なのですが、Webアプリケーションの中の権限管理ならば、必ずしもアイデンティティプールを利用する必要はありません。
Webアプリケーションの中で、ユーザー情報の管理とログイン機能を提供するだけであれば、ユーザープールだけでも十分と言えます。

本記事では、アイデンティティプールは一旦置いておいて、ユーザープールを利用して、Webアプリケーションに認証機能を追加する方法を説明します。

ロードバランサーとAmazon Cognitoの認証設定のイメージ

本記事では、ロードバランサーにApplication Load Balancer(ALB)を利用します。
ALBの配下にAmazon EC2を配置し、Webアプリケーションを構築します。

ALB+Amazon EC2によるWebアプリケーションの構成図

ALBは、Amazon Cognitoによる認証設定を行うことができます。
ここで一点注意事項があります。

ALBとAmazon Cognitoによる認証設定は、HTTPS(SSL/TLS)で通信が前提となります。
したがって、ALBにはSSL証明書を設定しておく必要があります。
この手順については割愛するため、事前にSSL証明書を設定してください。

認証設定を行うと、未認証のリクエストが来た場合、Amazon Cognitoのログイン画面にリダイレクトされるようになります。
ログインすると、ALBにリダイレクトされ、認証が完了した後に初めて元のリクエストがEC2に転送されるようになります。

しかし、実際のWebアプリケーションでは、全てのページに対して認証が必要なわけではありません。
TOPページやお問い合わせページなど、認証が不要なページもあるでしょう。

認証をかけたいページと、かけたくないページを分けるために、ALBの分岐設定(ルーティング設定)を行います。
ALBの設定構造は以下のようになっています。

graph TD;
    A[ALB] --> B[リスナー:443];
    B --> C[ルール] --> D[ターゲットグループ] --> E[Amazon EC2];
    B --> F[ルール] --> G[ターゲットグループ] --> H[Amazon EC2];

この図の3段目にあるルールが、リクエストの振り分けを行う部分です。
URLのパスによって、振り分けと認証設定の有無を指定することができます。

graph TD;
    A[ALB] --> B[リスナー:443];
    B --> C[ルール<br>/member/*<br>Cognito認証あり] --> D[ターゲットグループ] --> E[Amazon EC2];
    B --> F[ルール<br>上記以外<br>Cognito認証なし] --> G[ターゲットグループ] --> H[Amazon EC2];

このようにすることで、リクエストのパスが/member/から始まる場合だけ、認証していないとアクセスできないようにすることができます。
ちなみにこの時、ターゲットグループの先のEC2は同じものを指定しても問題ありません。

Amazon Cognitoのユーザープールの作成

では、ここから設定手順を説明していきます。
まずは、Amazon Cognitoのユーザープールを作成します。

AWSマネジメントコンソールのサービスからAmazon Cognitoを選択、ナビゲーションペインでユーザープールをクリック。
ユーザープールを作成をクリックします。

「ユーザープールを作成」をクリック

今回はMPAのWebアプリケーションを想定しているので、従来のウェブアプリケーションを選択します。
そして、アプリケーションの名前を入力します。

「従来のウェブアプリケーション」を選択して名前を入力

下にスクロールして、サインイン識別子のオプションサインアップのための必須属性を設定します。
サインイン識別子のオプションは複数指定可能です。
メールアドレス,電話番号,ユーザー名の3つにチェックを入れた場合、これらのどれかとパスワードの組み合わせでログインできるようになります。

サインインの識別子などを入力

そして、リターン URL を追加にURLを入力します。
ここに入力すべき文字列は、Cognitoと連携させるのがALBの場合、下記ページで指定された文字列に沿う必要があります。

docs.aws.amazon.com

IdP アプリで次のリダイレクト URL のいずれかを許可します。 ユーザーが使用するものであればどれでも構いません。 ここで DNS はロードバランサーのドメイン名であり、CNAME はアプリケーションの DNS エイリアスです。
https://DNS/oauth2/idpresponse
https://CNAME/oauth2/idpresponse

最後にユーザーディレクトリを作成するをクリックして、ユーザープールを作成します。

ユーザープールへのユーザー登録

ユーザープールが作成されたら、ユーザーを登録します。
Cognitoのナビゲーションペインから、作成したユーザープールを選択します。

次の画面の、ナビゲーションペインからユーザーを選択し、ユーザーを作成をクリックします。

ここでは、最低限の情報だけ入力することでユーザーを登録できます。
必要な情報を入力し、ユーザーを作成をクリックします。

Amazon Cognitoのユーザー作成画面

ユーザーに属性を追加する場合は、作成した後の編集画面から追加することができます。
作成されたユーザーをクリックします。

作成できたユーザーの名前をクリック

ユーザー属性編集をクリックします。

ユーザー属性欄の編集をクリック
ユーザー属性の編集画面で属性を追加することができるので、必要な属性を追加します。

ユーザー属性の編集画面で属性を追加することができる

これら一連の作業を行うことで、ユーザープールにユーザーを登録することができます。

ALBのAmazon Cognito認証設定

ユーザープールの準備ができたら、次はALBにAmazon Cognitoの認証設定を行います。
EC2の画面のナビゲーションペインで、ロードバランサーを選択、対象のALBを選択します。

リスナーとルールのタブをクリックします。
以下のように、HTTPSのリスナーが一つ存在し、デフォルトのルールが1つだけある状態から、ルールとCognitoの認証設定を追加していきます。
ルールを追加するをクリックし、ルールの新規作成画面を開きます。

任意の名前を入力し、次へをクリックします。

ルールの新規作成画面

条件の追加をクリックするとダイアログが表示されるので、パスを選択します。

条件の追加をクリック

条件の追加ダイアログで、「パス」を選択

パスを選択すると、文字列の入力欄が表示されるので、認証を必須とするページのパスを入力します。
ここでは/member/*を入力します。
これで、このルールはリクエストのパスが/member/で始まる場合のみ適用されるようになります。

認証を必須とするページのパスを入力

ダイアログの確認をクリック、そして次へをクリックします。

パス追加後の画面

次の画面で以下のように設定します。

  • OpenID または Amazon Cognito を使用するにチェックを入れる
  • アイデンティティプロバイダーで、Amazon Cognitoを選択
  • ユーザープールで、作成したユーザープールを選択
  • ユーザープールドメインは、ユーザープールを選択した時点で自動で入力されているのでそのまま
  • アプリケーションクライアントは、ユーザープールを作成すると一つ自動で作成されるはずなので、それを選択

ルールアクションの入力画面でAmazon Cognitoを指定

  • アクションのルーティングで、ターゲットグループへ転送を選択
  • ターゲットグループで、EC2のターゲットグループを選択、ここは認証設定を行わないルールと同じものでも構いません

ターゲットグループを設定する

優先度を設定し、次へをクリックします。
優先度は数字が小さいほど優先されます。
ここでは、1を設定しています。

優先度を設定する

最後の確認画面で、作成をクリックします。

確認画面で設定内容を確認

ルール作成後の画面はこちらのようになります。

ルール作成後の画面は

以上で、ALBにAmazon Cognitoによる認証設定が完了しました。
これで、リクエストのパスが/member/で始まる場合のみ、Amazon Cognitoの認証設定が適用されるようになります。

動作確認

設定が完了したら、実際に動作確認を行います。
ブラウザからALBのDNS名にアクセスし、/member/にアクセスすると、Amazon Cognitoのログイン画面が表示されるはずです。
ログインした後は、元のリクエストがEC2に転送され、/member/のページが表示されるはずです。
/member/以外のページにアクセスすると、Amazon Cognitoのログイン画面が表示されることなく、そのままページが表示されるはずです。

「/member/」アクセス時に表示されるログイン画面

今回の内容はここまでです。

次回の内容

実際のWebアプリケーションでは、アプリ独自の権限管理が必要になることが多いです。
権限管理を行うには、プログラムがログイン中のユーザー情報を取得できる必要があります。
今回認証の設定をしたALBで、認証した状態でリクエストすると、リクエストヘッダにJWTが含まれるようになります。
JWTは、ユーザー情報を含んでいるので、プログラムはこのJWTを解析してユーザー情報を取得することで、自身の権限管理に繋げることができます。
次回は、このJWTを使って、アプリケーション独自の権限管理を行う方法を説明します。

blog.serverworks.co.jp

兼安 聡(執筆記事の一覧)

アプリケーションサービス部 DS3課所属
2025 Japan AWS Top Engineers (AI/ML Data Engineer)
2025 Japan AWS All Certifications Engineers
2025 AWS Community Builders
Certified ScrumMaster
PMP
広島在住です。今日も明日も修行中です。