[前回] AWS公式資料で挑むSCS認定(12)-AuditManager
はじめに
「道に迷うのは目標を見失ったからだ」、3/19の認定試験、意識しなくちゃ。。。
今回も「Security, Identity & Compliance」に分類されるサービスシリーズです。
Amazon Cognito は、モバイル・Webアプリ向けのユーザ認証を提供してくれるようです。
教材を選ぶ
変わらず、AWS Black Belt Online Seminar資料Amazon Cognitoを使用します。
ユーザ認証の全体像から入り、Amazon Cognitoの機能/位置づけを体系的に解説。
ユーザ認証の実装に必要なAPI選定、実装方法まで盛り込まれている、感謝感謝。
ユーザ認証の選択肢
アプリの特性、対象ユーザ、認証要件などに応じた選択肢。
ユーザ認証の「森」(全体像)を一望できるこの一枚、自分の中では本資料のベストスライドでした。
引用元: https://d1.awsstatic.com/webinars/jp/pdf/services/20200630_AWS_BlackBelt_Amazon%20Cognito.pdf
Amazon Cognito とは
API ベースで実装されるモバイルアプリや Web アプリにユーザ認証機能を提供するサービス。
アクセス先がアプリかAWSかにより、
- ユーザプール
- アプリへのアクセスに利用できるトークンを提供
- 独自のユーザディレクトリに加え、外部 ID プロバイダでのログインに基づく
- ID プール(フェデレーティッド アイデンティティ)
- AWS にアクセスできるクレデンシャルを提供
- Cognito ユーザプールに加え、外部 ID プロバイダでのログインに基づく
ユーザプール
ユーザ
ユーザは管理者が作成、またはユーザ自身でサインアップ。
外部IDプロバイダのユーザは初回サインイン時に情報を自動登録。
ユーザ属性
- Cognito固有のユーザ情報
- Username
- UserStatus
- PreferredMfaSetting
- roles
- 標準属性 (OIDC仕様)
- phone_number
- preferred_username
- name
- カスタム属性
- 頻繁に参照・変更・検索する情報については DB に保存する方が望ましい
- サインインに使用したデバイス情報(有効時のみ記録)
- デバイスキー
- 名前
- 最後の IP
- SDK
- 最後の利用日時
ユーザのステータス
-
サインアップ時
- UNCONFIRMED(=サインインはまだ不可)
- CONFIRMED
- RESET_REQUIRED
- FORCE_CHANGE_PASSWORD
- DISABLED
- (Deleted)
-
外部IDプロバイダから初回サインイン時
- EXTERNAL_PROVIDER
- DISABLED
- (Deleted)
ユーザグループ
- ユーザは複数のグループに入れることが可能
- グループは属性としてアプリケーションから確認できる
- Cognito ID プールとの連携で利用できる IAM ロールやその優先順位の指定に使用できる
アプリクライアント
アプリクライアントとは
- アプリケーションは、「API 呼び出し、Hosted UI の利用、OAuth による認可」を行うためにユーザプールにアクセスする
- アプリクライアントは、ユーザプールにアクセスするこれらのアプリケーションを登録し、利用できる機能や権限を設定
- 登録されたアプリケーションは IAM クレデンシャルを利用せずにアクセスできる
アプリクライアントの識別
アプリクライアントID、シークレットでアプリケーションを識別
アプリクライアントの種類
- パブリッククライアント
- シークレットを割り当てないクライアント
- ブラウザ上の JavaScript などシークレットを保護できない環境の場合
- プライベートクライアント
- シークレットを割り当てるクライアント
- サーバなどの環境
サインインの実装
利用できる2種類のAPI
-
Cognito Identity Provider APIを利用
引用元: https://d1.awsstatic.com/webinars/jp/pdf/services/20200630_AWS_BlackBelt_Amazon%20Cognito.pdf
- 呼び出し元によって異なる API
- 管理者としてサーバ側から呼び出す前提の Admin API
- IAM ロールのクレデンシャルを使用
- ユーザとしてサーバ側からもクライアン側からも呼び出せる API
- アプリクライアントID(+ シークレット)を使用
- 管理者としてサーバ側から呼び出す前提の Admin API
- サインインは下記認証フローを指定して API を呼び出す
- USER_SRP_AUTH
- SRPプロトコルに基づき、パスワードを基にしたチャレンジレスポンスで認証する
- サーバ側でも元のパスワードは不明な状態になるなど安全な方法
- CUSTOM_AUTH
- 認証時に Lambda ファンクションがトリガーされる
- ファンクション次第で追加の認証を行って認証などができる
- USER_PASSWORD_AUTH
- SRPプロトコルを使用せず、パスワード自体を送って認証する
- クライアントからは USER_SRP_AUTH の利用を推奨
- ADMIN_USER_PASSWORD_AUTH
- USER_PASSWORD_AUTH と似ているがサーバ用 API からのみ呼び出せる
- REFRESH_TOKEN_AUTH
- 更新トークンから新しいトークンをもらう。
- USER_SRP_AUTH
- 呼び出し元によって異なる API
-
Cognito Auth API とHosted UI を利用
引用元: https://d1.awsstatic.com/webinars/jp/pdf/services/20200630_AWS_BlackBelt_Amazon%20Cognito.pdf
- Cognito がマネージドサービスの一部として、サインアップ、サインイン、パスワード忘れの対応が行えるWeb UIを提供
- 多要素認証(MFA)に対応
- カスタム認証フローのような仕組みはなし
- ドメイン名、UI のロゴ、CSS のカスタマイズが可能だが、日本語対応は不可
- 外部 ID プロバイダーを使ったサインインには Auth API が必須
- OAuth を使ったサードパーティアプリへの認可には Auth API と Hosted UI が必須
- 認証は OAuth 2.0 で定義されているフローに沿って行う
- 認証後アプリには認可コードあるいはトークンを URL パラメータなどに付けてリダイレクトされる
- Authorization Code Grant(認可コード許可)
- Implicit Grant(暗黙的許可)
- Authorization Code Grant の方がセキュアで推奨
- 認証後アプリには認可コードあるいはトークンを URL パラメータなどに付けてリダイレクトされる
- Cognito がマネージドサービスの一部として、サインアップ、サインイン、パスワード忘れの対応が行えるWeb UIを提供
要件に応じたAPI選択
- ユーザプール独自のユーザを利用する場合
- 外部 IDプロバイダを利用する場合
- Cognito Identity Provider API &
- Cognito Auth API
- 外部 IDプロバイダを利用しない場合
- Cognito Identity Provider API
- 外部 IDプロバイダを利用する場合
- ユーザプール独自のユーザを利用しない場合
- Cognito Auth API
サインイン実装には SDK や Library を利用する
API 呼び出しを直接実装する必要はない
サインイン後の実装
発行されるトークン
- 各トークンはJWT形式(OAuth/OIDC同様)
- トークンの署名は以下の公開鍵で検証できる
トークンの種類と用途
- ID トークン
- Cognito ID プールにアクセス
- ユーザの属性が含まれる(カスタム属性含む)
- アクセストークン
- Identity Provider API にユーザとしてアクセス
- 一部のユーザ情報に加えスコープなどが含まれる
- 更新トークン
- IDトークン・アクセストークンを更新
- サインインの方法によっては更新トークンは発行されない
トークンをアプリケーションの API アクセスに利用
- トークンを利用してアプリAPIのサーバへアクセス
- 公開キーでトークンの署名を検証
- API Gateway経由でLambdaへアクセス
- COGNITO_USER_POOLSオーソライザー
- AWS AppSync経由でDynamoDB, Lambdaへアクセス
- AMAZON_COGNITO_USER_POOLS認証
- ALB(Application Load Balancer)経由でEC2へアクセス
- Cognito認証
- Cognito Auth API & Hosted UI 前提
- APIベースでは無いWebアプリへのアクセスにCognito のサインインを条件にできる
トークンをAWSのAPIアクセスに利用
処理の流れ:
- クライアントからユーザプールへリクエストし、ID トークンが発行される
- クライアントから 1.の IDトークンを使って Cognito IDプールへリクエストし、AWS一時クレデンシャルが発行できる
- クレデンシャルが発行される IAM ロールを指定できる
- クレデンシャルには cognito-identity.amazonaws.com:sub などの変数が設定される
- AWS一時クレデンシャルを使って、S3などへアクセス
サインアウト
共用端末でユーザ本人以外が同じクライアントを利用できないように、サインアウトを実装。
どのようにトークンを使っているかによって、行うべき対処が異なる:
- 共通
- トークンをアプリやSDKでクライアントから破棄
- アクセストークン・ID トークン自体は最大1時間の有効期限内は利用可能
- Identity Provider API(ユーザとしての呼び出し(更新トークンの利用を含む))
- グローバルサインアウトで無効化
- Auth API(Hosted UI からの再サインイン)
- ログアウトエンドポイントで無効化
サインインに利用できる外部 ID プロバイダ
Auth API を使うと、外部 ID プロバイダでのサインインに基づいて、Cognito ユーザプールにサインインできる。
ユーザ登録や新たなパスワードの記憶などの手間を省くことができる。
- Login with Amazon
- Sign In with Apple
- SAML (SP-Initiated限定)
- OpenID Connect (OIDC)
※ SAML や OIDC を使うと数多くのIDプロバイダに対応できる
Cognitoのセキュリティ強化機能
- 電話番号と Email の検証
- 多要素認証(MFA)の利用
- SMS テキストメッセージ
- TOTP ソフトウェアトークン
- クライアントデバイスの追跡
- アドバンスドセキュリティの機能
- 侵害された認証情報が使われていないか確認
- アダプティブ認証
- リスクに応じて MFA の利用を求めたり、ブロックしたりする
Cognitoの監視
-
Amazon CloudTrailによるログ記録
- Cognito API 呼び出しログが記録され、監査やトラブルシューティングに使用
- APIの記録可否
- 〇 Cognito Identity Provider API
- ☓ Cognito Auth API や Hosted UI
- △ サインインしたユーザの情報やセキュリティ情報は記録されないが
- Lambdaトリガー内で出力する事で実現できる
-
Amazon CloudWatchによるモニタリング
- CloudWatch メトリックにイベントの発生が記録
- ユーザによる使用状況やスロットリング(制限超過)の発生を確認できる
- 一部の API を対象にユーザプール、アプリクライアントごとに以下が記録
- サインアップの成功/スロットリング
- サインインの成功/スロットリング
- トークン更新の成功/スロットリング
- フェデレーションの成功/スロットリング
ユーザプールの特徴まとめ
- サーバーレスで認証とユーザ管理
- サーバについて心配することなく、サインアップ、サインイン機能を実現
- サードパーティとの連携が充実
- 外部 ID プロバイダを使ったサインイン機能
- OAuth を使ってサードパーティアプリへの認可も実現
- 強力なセキュリティ機能
- 電話番号やEmailアドレスの検証や多要素認証を実現
- アダプティブ認証も実現
おわりに
Amazon Cognitoが提供する豊富な認証機能から、認証の重要性が窺えます。
次回は、Amazon Detectiveです。お楽しみに。