【レポート】サーバーレスにおける認証と認可: サーバーレスアプリケーションのためのID管理 #reinvent #SRV403

SRV403 - Serverless Authentication and Authorization: Identity Management for Serverless Applications

ラスベガスで開催中のre:Invent 2017にて「SRV403: Serverless Authentication and Authorization: Identity Management for Serverless Applications」を聴講してきたのでレポートします。

スピーカーは下記の2名です。

  • Vlasmir Budilov
  • Justin Pirtle

はじめに

  • サーバレスAPIアーキテクチャに高度に精通していることを前提としています(API Gateway, Lambda)
  • 以下を使用した、サーバーレスアプリにID管理を実装する方法を学びます
    • Amazon Cognito User Pools
    • Amazon Cognito Fadarated Identities
    • Amazon API Gateway
    • AWS Lambda
    • AWS Identity and Access Management(IAM)

サンプルアプリ「Space Finder」がオープンソースで公開中

GitHubで、「Space Finder」という部屋を管理するサンプルアプリが公開中です。オープンソース(Apacheライセンス2.0)です。

ID管理

パスワードの保管方法

  • サインアップとサインインに必要な情報は、ユーザー名、メールアドレス、パスワード
  • パスワードの保管方法がセキュリティ上大事
    • × パスワードをそのまま保管する
    • プレーンなテキストとして保存され続ける
    • 不正なユーザーに対する脆弱性
    • DBがハックされると全てのユーザーの損害になる
    • × ハッシュ化されたパスワード
    • MD5/SHA1の衝突
    • レインボーテーブル
    • ブルートフォースアタックに弱い
    • △ ソルトを使ってハッシュ化されたパスワード
    • アプリのソルト+ユーザーのソルトの組み合わせ
    • ブルートフォースアタックの速度を落とす程度
    • ◯ SRP(Secure Remote Password)
    • セキュアなパスワードのハンドリングが可能

Cognito User PoolsはID管理に必要な機能と高度なセキィリティ要件を満たす

  • ユーザーフロー
    • 登録
    • メードアドレス・電話番号の検証
    • セキュアなサインイン
    • パスワード再発行
    • パスワード変更
    • サインアウト
  • セキュリティ要件
    • セキュアなパスワードのハンドリング
    • 多要素認証
    • パスワードポリシーの強制
    • 全てのデータのサーバーサイド暗号化
    • カスタム認証フローのサポート
    • 100sミリオンのユーザーに耐えうるスケーラビリティ

サインアップとサインインのフロー

基本

  1. 登録
  2. SNSまたはEmailによる認証
  3. 登録確認
  4. 登録完了
  5. 認証(via SRP)
  6. JWTトークンの返却

認証のカスタム

  • 認証処理について、Lambdaを用いたカスタムの認証処理(Authentication Challenge)も使える
  • 例 : CAPTCHA、カスタムMFA
  • クライアントはChallenge Responseを投げる
  • Lambdaを用いたChallenge Responseの検証(Verify Authentication Challenge Response)が実行できる
  • Challenge Responseが正規のものだったらJWT Tokenを返却する
  • さらなるカスタムフローが追加可能
    • サインアップ前のバリデーション
    • ユーザー検証のカスタムロジック
    • 認証前のバリデーション
    • 認証チャレンジの定義
    • 認証チャレンジのバリデーション
    • 認証処理のカスタムロジック

JWT Token

  • HeaderとPayloadとSignatureに分解できる
  • Payloadに載せるユーザー情報はカスタマイズできる

Application so far...

Cognito User PoolsとCognito Federated Identityを組み合わせて、S3にファイルを直接アップロードする機能を題材に考えます。

次のフローで認証と認可を実施します。

  1. Cognito User Poolsで構築したIdentity Providerに対してサインインする
  2. Cognito Federated IdentitiesにJWT Tokenを渡し、STS Tokenを取得する
  3. Cognito Federated IdentitiesがSTSに一時的なAWS認証情報を要求し、STS Tokenを返す
  4. STS Tokenを使ってAWSリソースにアクセスする

ユーザーごとに異なるパーミッションを与えるには、Fine-grained Role-Based Access Controlを使います。

  • ユーザーを、Unauthenticated Users(未認証、匿名)とAuthenticated Users(認証済み)に分ける
  • それぞれにDefault Roleを付与する
  • Authenticated Usersには、さらに細かな指定ができる
    • ルールを元にしたロールを適用できる
    • トークンを元にしたロールを適用できる
  • これらにより、ユーザーのロールを柔軟に決めることができる

最もセキュアなのはIAM(STSトークン)であると話していました。

デモ: S3へのアップロードを行う

サインアップ後、S3に対して画像をアップロードする機能のデモの実演です。

まずモバイルアプリからサインアップを行い、メールで認証コードを送信します。

サインアップを行うと、登録したメールアドレス宛にメールが到着します。本文に数字6桁の番号が記載されています。これを認証コードとして使うことで「認証済みのユーザー 」であると見なせます。

JWTトークンが返却されるので、以降ははJWTトークンを使ってAPI認可させます。

以降はAPI Gatewayに対して、JWTトークンをヘッダーに付与することでリクエストできるようになります。S3にファイルを直接アップロードし、一覧で見るといったこともできます。

JWTトークンにユーザー情報の何を含めるか指定できます。

1つのCognito User Poolに対して、複数のApp Clientを作成できます。

Cognito Federated IdentityとCognito User Poolsは密に連携させることができます。

認証基盤はどれを使えば良い?

  • Cognito User Pools: Pools Ththorizers
  • Cognito Federated Identities: AWS IAM Authorization
  • Custom Identities Probvoder: Custom Authorizer

Migrating to Cognito User Pools

Cognitoの認証基盤への移行について、2つの手段のいずれかを使うことができます。

その1: バルクインポート

  1. CSVを作成する
  2. CSVで丸ごとバルクインポート
  3. 初回ログイン時にパスワードを変更

その2: ユーザーにお任せ

  1. Cognito User Poolsに対して通常通りサインインしようとしてもらう
  2. サインインに失敗したときフロントは既存の認証基盤にリクエストする
  3. サインインに成功したら、同じユーザー名とパスワードでサインアップさせます

感想

Cognitoの認証機能について、これまでのアップデートをおさらいできる良いセッションでした。Advanced Security Featureもサポートするアップデートもありましたし、これからの発展にますます期待ですね。