背景・目的
私は、現在データエンジニアリングを生業としています。普段は、データ基盤の構築や、パフォーマンスチューニングなどビックデータに関する業務に従事しています。
日頃から、データに関わる業務が多く、Webフロントエンドやバックエンドの技術に触れる機会が少ないため、意図的に学んで行こうと思います。
今回は、Webアプリケーションの認証やユーザ管理のサービスであるAmazon Cognito(以降、Cognitoと言います。)を学んでいこうと思います。
まとめ
- Cognitoは、簡単な設定でユーザ認証の仕組みを提供する。
- 既存のシステムや他のIdPで管理しているユーザIDを使用することが可能。
概要
Cognitoとは?
Amazon Cognito を使用すれば、ウェブアプリケーションおよびモバイルアプリに素早く簡単にユーザーのサインアップ/サインインおよびアクセスコントロールの機能を追加できます。Amazon Cognito は、数百万人のユーザーにスケールし、Apple、Facebook、Google、Amazon などのソーシャル ID プロバイダー、SAML 2.0 および OpenID Connect によるエンタープライズ ID プロバイダーを使用したサインインをサポートします。
- 対象はウェブ、モバイルアプリ
- 機能は、認証、承認、ユーザ管理
- サインインは、ユーザ名とパスワードの直接か、サードパーティを通じてサインイン可能。
- SAML2.0、OpenID ConnectによるエンタープライズIDはプロバイダーを使用したサポートしている。
Amazon Cognito の主な 2 つのコンポーネントは、ユーザープールと ID プールです。ユーザープールは、アプリユーザーのサインアップとサインインオプションを提供するユーザーディレクトリです。ID プールは、AWS の他のサービスに対するアクセスをユーザーに許可します。ID プールとユーザープールは別々に使用することも、一緒に使用することもできます。
- 以下の2つのコンポーネントで構成されます。個別に利用、一緒に利用も可能です。
- ユーザプール
- ユーザディレクトリ
- アプリユーザのサインアップ、サインインオプションを提供する。
- IDプール
- AWSの他のサービスに対するアクセスをユーザに許可する。
- ユーザプール
Amazon Cognito のユーザープールと ID プールの併用
認証から、AWSサービスにアクセスまでの流れを記載します。
※ 出典:Amazon Cognitoとは?から抜粋しています。
- アプリのユーザーはユーザープールを介してサインインし、認証が成功するとユーザープールトークンを受け取ります
- アプリケーションが ID プール経由でユーザープールトークンを AWS 認証情報と交換します。
- アプリケーションユーザーがこれらの AWS 認証情報を使用して、Amazon S3 または DynamoDB などの AWS のその他サービスにアクセスできるようになります。
Amazon Cognito の機能
ユーザープール
ユーザープールは、Amazon Cognito のユーザーディレクトリです。ユーザープールを使用することで、ユーザーはウェブまたはモバイルアプリに Amazon Cognito 経由でサインインする、またはサードパーティー ID プロバイダー (IdP) 経由でフェデレートすることができます。ユーザーが直接またはサードパーティーを通じてサインインするかどうかにかかわらず、ユーザープールのすべてのメンバーには、SDK を通じてアクセスできるディレクトリプロファイルがあります。
ユーザープールは次の機能を提供します。
- サインアップおよびサインイン。
- ユーザーをサインインするためのカスタマイズ可能な組み込みWeb UIの提供
- Facebook、Google でのソーシャルサインイン、Login with Amazon、Sign in with Apple、ユーザープールからの SAML および OIDC ID プロバイダー経由のサインイン。
- ユーザーディレクトリとユーザープロファイルの管理。
- 多要素認証 (MFA) などのセキュリティ機能、漏洩した認証情報のチェック、アカウントの乗っ取りからの保護、電話とEメールによる検証。
- カスタマイズされたワークフローと AWS Lambda トリガーによるユーザー移行。
Amazon Cognito ユーザープールは、何百万人ものユーザーにスケールするセキュアな ID ストアを提供します。Cognito ユーザープールは、インフラストラクチャのプロビジョニングを行うことなく、より簡単に設定することができ、ユーザープールのすべてのメンバーは、ソフトウェア開発キット (SDK) を通じて管理できるディレクトリプロファイルを持っています。
- スケールするセキュアなIDストアを提供
ID プール
ID プールを使用すると、ユーザーは Amazon S3 や DynamoDB などの AWS のサービスにアクセスするための一時的な AWS 認証情報を取得できます。
- AWSサービスにアクセス可能な一時的なクレデンシャルを取得できる。
ID プールは、匿名ゲストユーザーと、ID プールのユーザーを認証するのに使用できる次の ID プロバイダーをサポートします。
IdPの一覧。
- Amazon Cognito user pools
- Facebook、Google でのソーシャルサインイン、Login with Amazon、Sign in with Apple
- OpenID Connect (OIDC) プロバイダー
- SAML ID プロバイダー
- デベロッパーが認証した ID
一般的な Amazon Cognito シナリオ
6つの一般的なシナリオを以下に記載します。
ユーザープールを使用して認証する
ユーザーがユーザープールを使用して認証できるようにすることが可能。
アプリユーザーは、ユーザープール経由で直接サインインする、またはサードパーティーの ID プロバイダー (IdP) 経由でフェデレートする事が可能。
認証が正常に行われると、ウェブまたはモバイルアプリがCognito からユーザープールトークンを受け取る。
このトークンは、アプリケーションがAWSのその他サービスにアクセスできるようにする AWS認証情報の取得に使用できる。
その他にサーバー側のリソースやAPIGateway へのアクセスを制御するために使用することも可能。
ユーザープールを使用してサーバー側のリソースにアクセスする
サインインが正常に行われると、ウェブまたはモバイルアプリがCognito からユーザープールトークンを受け取る。
サーバ側へのアクセスを制御するには、このトークンを利用する。
また、ユーザプールグループを作成して許可を管理したり、異なるタイプのユーザを管理したりできる。
※ 出典:一般的な Amazon Cognito シナリオから抜粋。
ユーザプールのドメインを設定するとCognitoがサインインアップ、サインインするページを追加できるHosted Web UIをプロビジョニングする。
このOAuth2.0認証基盤を利用すると、独自のリソースサーバを作成してユーザは保護されたリソースにアクセスできる。
ユーザープールと共に API Gateway と Lambda を使用してリソースにアクセスする
ユーザーが API Gateway 経由で API にアクセスできるようにすることが可能。
APIGateway は、正常に行われたユーザープール認証からのトークンを検証し、これらのトークンを Lambda関数などのリソース、または独自のAPIへのアクセス権をユーザーに付与するために使用する。
ユーザープール内のグループは、グループメンバーシップを IAM ロールにマップすることによって、API Gateway でアクセス許可を制御するために使用可能になる。
CognitoオーソライザーのLambda関数による検証のために、APIGatewayへのリクエストでユーザープールトークンを送信する事が可能。
※ 出典:一般的な Amazon Cognito シナリオから抜粋。
ユーザープールと ID プールを使用して AWS のサービスにアクセスする
ユーザープールの認証後に、アプリケーションがCognito からユーザープールトークンを受け取り、IDプールを使用したAWSの他のサービスへの一時的なアクセス権と交換できる。
※ 出典:一般的な Amazon Cognito シナリオから抜粋。
サードパーティーで認証を行い、ID プールを使用して AWS サービスにアクセスする
ユーザーが IDプール経由でAWSのサービスにアクセスできるようにすることが可能。
ID プールには、サードパーティー ID プロバイダーによって認証されたユーザーからの IdP トークンが必要。※匿名ゲストの場合は何も必要なし。
IDプールは、AWSの他のサービスへのアクセスに使用できる一時的なAWS認証情報を付与する。
※ 出典:一般的な Amazon Cognito シナリオから抜粋。
Amazon Cognito を使用して AWS AppSync リソースにアクセスする
正常に行われたCognito 認証 (ユーザープールまたは ID プール)からのトークンを使用して、AppSyncへのアクセス権をユーザーに付与することが可能。
※ 出典:一般的な Amazon Cognito シナリオから抜粋。
実践
Amazon Cognito チュートリアルを元に試してみます。
ユーザプール
ステップ 1. ユーザープールを作成します。
1.Cognitoのマネコンで「ユーザプールの管理」をクリックします。
3.プール名に「TestUserPool」を入力後、「デフォルトを確認する」をクリックします。
4.画面左のナビゲーションペインにある「属性」をクリックします。
5.以下を選択し、「次のステップ」をクリックします。
- 「Eメールアドレスおよび電話番号」のラジオボタン
- 「Eメールアドレスを許可」のラジオボタン
6.画面左のナビゲーションペインにある「確認」をクリックします。
ステップ 2. アプリケーションを追加して、ホストされたウェブの UI を有効にする
1.ユーザプール管理画面で、「TestUserPool」をクリックします。
2.画面左のナビゲーションペインにある「アプリクライアント」をクリックします。
4.以下を設定し、「アプリクライアンの作成」をクリックします。
- アプリクライアント名に「TestAppClient」を入力
- 「クライアントシークレットを生成」のチェックボックスをオフ(※1)
※1 理由は、以下のとおりです。
この演習では、[Generate client secret] (クライアントシークレットを生成する) オプションをオフにします。この演習で使用する JavaScript など、クライアント側の認証でクライアントシークレットを使用することは安全ではなく、本番アプリケーションケーションクライアントには推奨されません。クライアントシークレットは、アプリケーションのサーバー側の認証コンポーネントでクライアントシークレットを保護できる場合にのみ使用します。
5.アプリクライアントIDが表示されるので、書き留めて「プールの詳細に戻る」をクリックします。
6.画面左のナビゲーションペインにある「アプリクライアントの設定」をクリックします。
7.以下を入力します。
- 有効なIDプロバイダ「Cognito User Pool」を選択
- コールバックURL
- ユーザーが認証された後で呼び出す画面
- サインアウトURL
- サインアウト後に呼び出される画面
8.以下を入力し、「変更を保存」をクリックします。
- 許可されているOAuthフロー
- Authorization code grant
- Implicit grant
- 許可されているOAuthスコープ
- phone
- openid
- aws.cognito.signin.user.admin
- profile
[Authorization code grant (認証コードの付与)] を選択して、ユーザープールトークンと交換される認証コードが返されます。トークンはエンドユーザーに直接公開されないため、侵害される可能性は低くなります。ただし、ユーザープールトークンの認証コードを交換するために、バックエンドでカスタムアプリケーションが必要です。セキュリティ上の理由から、モバイルアプリ用の認証コード付与フローとコード交換用証明キー (PKCE) を併用することをお勧めします。
[Allowed OAuth Flows] (許可されている OAuth フロー) で [Implicit grant] (暗黙の付与) を選択し、Amazon Cognito からユーザープールの JSON Web トークン (JWT) が返されるようにします。このフローは、トークンの認証コードを交換できるバックエンドがない場合に使用でき、トークンのデバッグにも役立ちます。
9.画面左のナビゲーションペインにある「ドメイン名」をクリックします。
10.ドメイン名を入力し、使用可能かチェックし、最後に「変更を保存」をクリックします。
11.画面左のナビゲーションペインにある「アプリクライアントの設定」をクリックします。
13.ログインページが表示されるので、サインアップをクリックします。
14.指定したemailアドレスに、verification codeが送られるので入力します。
15.コールバックURLに指定したHTMLが表示されました。(表示されているのは、自分で用意した適当な画面です。)
18.ログアウトのURLにアクセスします。(表示されているのは、自分で用意した適当な画面です。)
考察
今回は、Cognito内にアイデンティティストアを用意しました。次回は、IdPと連携した場合を試してみます。
参考