SlideShare a Scribd company logo
AWS にアップロードしたファイルに認証
をつける
Ryosuke Takeuchi
目次
 本ドキュメントの目的
 システム構成
 使用するサービス一覧
 システム全体像
 処理フロー
 構築手順
1. S3のバケットにファイルをアップロードする
2. CloudFrontを作成しS3バケットをオリジンに設定する
3. Cognitoユーザープールを設定する
4. 認証処理用のLambda関数を実装しデプロイする
5. CloudFrontにLambda@Edgeをデプロイする
 付録
 無料枠と料金について
 他の方式との比較
本ドキュメントの目的
• AWS のサービスを組み合わせることで、認証されたユーザーだけがファイル
にアクセスできるような仕組みを構築することができます
背景
解決策
本ドキュメン
トの目的
• ユーザーに対してファイルを配信したいが、制限されたユーザーだけがアク
セスできるようにしたい ( アクセスできるユーザーを制御したい )
• ファイル保存先の URL が流出しても、第三者が不正にアクセスできないよう
にしたい
• クラウドにアップロードしたファイルに認証をつけるためのシステム構成と
構築手順について説明します
アクセスを許可したユー
ザー
その他のユーザー
使用するサービス一覧
システム構成
サービス名 アイコン 機能
Amazon Simple Storage
Service (Amazon S3)
• 画像、動画などのファイルをクラウド上に保存できる
ストレージサービス
Amazon CloudFront • コンテンツ配信サービス
• S3 に保存したファイルを全世界に高速で配信するこ
とができる
• S3 と組み合わせてセキュリティの向上やその他の追
加機能を実装することができる
AWS Lambda • ユーザーからリクエストがあった時だけ起動して処理
を実行する
• Lambda@Edge: ユーザーが CloudFront にアクセスし
た際に特定の処理を実行できる
Amazon Cognito • ユーザー管理サービス
• ログイン機能を簡便に追加できる
• パスワード認証や、 Google/Facebook ログインなど
を設定することもできる
Amazon CloudWatch • AWS で使用している各サービスのログを監視できる
システム全体像
システム構成
AWS Cloud
AWS Lambda
Amazon Simple Storage
Service (Amazon S3)
Amazon CloudFront
Amazon Cognito
Amazon CloudWatch
認証されていないユーザーからのアクセ
スは拒否
ログ出
力
認証処理実行
アクセス時に
Lambda@Edge
実行
Cognito の認証済ユーザーだけアクセス許可
index.html
cat.jpg
処理フロー (1)
システム構成
処理フロー (2)
システム構成
(1) バケットを作成する
1. S3 のバケットにファイルをアップロードする
S3 の画面から ”バケットを作成” ボタンを押す。すべてデフォルト設定でバケットを作成する
デフォルト設定ではパブリックアクセスはすべてブロックされる
(2) バケットにファイルをアップロードする
1. S3 のバケットにファイルをアップロードする
バケットの画面から “アップロード” を押し、ファイルを選択してアップロードする
(3) 動作確認
1. S3 のバケットにファイルをアップロードする
アップロード後、オブジェクト URL にアクセスすると “ Access Denied” になっていることを確
認する
作業後の状態
1. S3 のバケットにファイルをアップロードする
AWS Cloud
AWS Lambda
Amazon Simple Storage
Service (Amazon S3)
Amazon CloudFront
Amazon Cognito
Amazon CloudWatch
認証されていないユーザーからのアクセ
スは拒否
ログ出
力
認証処理実行
アクセス時に
Lambda@Edge
実行
Cognito の認証済ユーザーだけアクセス許可
index.html
cat.jpg
パブリックアクセスを
ブロックしているため
どの経路でもアクセス
できない
(1) ディストリビューションを作成する
2. CloudFront を作成し S3 バケットをオリジンに設定する
CloudFront から “ディストリビューションを作成” に進む
“ オリジン” セクションで作成したバケット名を選択する。オリジンアクセスで “ Origin access
control settings” を設定
(2) Origin Access Control の設定
2. CloudFront を作成し S3 バケットをオリジンに設定する
すべてデフォルト設定で作成する
Origin Access Control(OAC)
• CloudFront のオリジンへの直接アクセスを制限する
• 今回は CloudFront で認証処理を設定するため、 CloudFront 経由のアクセスに制限すること
で認証が必ず実行されるようにする
(3) バケットポリシーの更新
2. CloudFront を作成し S3 バケットをオリジンに設定する
バケットの設定画面から “アクセス許可” > “ バケットポリシー” に進み、”編集” を押す
(3) バケットポリシーの更新
2. CloudFront を作成し S3 バケットをオリジンに設定する
バケットポリシーの編集画面で下記のポリシーを設定
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::static-site-auth-testing/*",
"Condition": {
"StringEquals": {
“AWS:SourceArn”: “< 作成したディストリビューションの ARN>"
}
}
}
]
}
(4) 動作確認
2. CloudFront を作成し S3 バケットをオリジンに設定する
“ 一般” タブからディストリビューションドメイン名をコピーし、末尾に /index.html を付与した
URL でアクセスできることを確認する
作業後の状態
2. CloudFront を作成し S3 バケットをオリジンに設定する
AWS Cloud
AWS Lambda
Amazon Simple Storage
Service (Amazon S3)
Amazon CloudFront
Amazon Cognito
Amazon CloudWatch
認証されていないユーザーからのアクセ
スは拒否
ログ出
力
認証処理実行
アクセス時に
Lambda@Edge
実行
Cognito の認証済ユーザーだけアクセス許可
index.html
cat.jpg
CloudFront 経由のア
クセスだけが許可され
ている
認証処理は未実装のた
め、すべてのユーザー
がアクセスできる
(1) ユーザープールを作成する
3. Cognito ユーザープールを設定する
“Amazon Cognito” > “ ユーザープール” からユーザープール作成に進む
(2) アプリケーションの定義
3. Cognito ユーザープールを設定する
サインイン識別子はメールアドレスに設定して ”作成” を押す
(3) テスト用ユーザーを作成する
3. Cognito ユーザープールを設定する
“ ユーザー” タブからテスト用のユーザーを作成する。仮パスワードセクションは ”パスワードの
生成” を選択
(4) テスト用ユーザーでログインする
3. Cognito ユーザープールを設定する
ユーザー作成後に下記のようなメールで仮パスワードが通知されることを確認する
“ アプリケーションクライアント” から登録したアプリケーションを開き、”ログインページを表
示” をクリックする
(4) テスト用ユーザーでログインする
3. Cognito ユーザープールを設定する
仮パスワードでログイン後、パスワードを更新してログインページに入れることを確認する
(1) Lambda 関数の実装
4. 認証処理用の Lambda 関数を実装しデプロイする
下記コマンドで npm プロジェクトを初期化する
$ mkdir lambda-at-edge # 作業用ディレクトリ作成
$ npm init # npm プロジェクト初期化
$ touch index.js # index.js ファイル作成
$ npm install cognito-at-edge # ライブラリインストール
const { Authenticator } = require("cognito-at-edge");
const authenticator = new Authenticator({
region: "< 認証に使用するユーザープールを作成したリージョン >",
userPoolId: "< ユーザープール ID>",
userPoolAppId: "< クライアント ID>,
userPoolAppSecret: "< クライアントシークレット >",
userPoolDomain: "< ユーザープールのドメイン >",
});
exports.handler = async (request) => authenticator.handle(request);
index.js に以下のコードを追加
CloudFront にデプロイする Lambda@Edge はサイズ制限がある ( ビューワーリクエストに紐づけ
る場合は 1MB)
下記コマンドでバンドルすることでサイズを圧縮してから、 ZIP ファイルを作成する
$ npx esbuild --bundle index.js --minify --outfile=bundle.js --platform=node # バン
ドル
$ zip bundle.zip bundle.js # Lambda にアップロードするために ZIP ファイル作成
(2) Lambda 関数の作成
4. 認証処理用の Lambda 関数を実装しデプロイする
バージニア北部 (us-east-1) で関数を作成する
“ 実行ロール” セクションで、ポリシーテンプレートから ”基本的な Lambda@Edge のアクセス権
限” を選択し、新しいロールを作成して設定する
(3) Lambda 関数のデプロイ
4. 認証処理用の Lambda 関数を実装しデプロイする
Lambda 関数の画面から “アップロード元” > “.zip ファイル” を選択しバンドルしたファイルから
作成した ZIP ファイルをアップロードする
(3) Lambda 関数のデプロイ
4. 認証処理用の Lambda 関数を実装しデプロイする
“ ランタイム設定” からハンドラを “ bundle.handler” に更新する
(3) Lambda 関数のテスト
4. 認証処理用の Lambda 関数を実装しデプロイする
“ イベント JSON” に以下の JSON を入力して実行し、正常終了することを確認する
{
"Records": [
{
"cf": {
"config": {
"distributionDomainName": "d111111abcdef8.cloudfront.net",
"distributionId": "EDFDVBD6EXAMPLE",
"eventType": "viewer-request",
"requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
},
"request": {
"clientIp": "203.0.113.178",
"headers": {
"host": [
{ "key": "Host", "value": "d111111abcdef8.cloudfront.net" }
],
"user-agent": [{ "key": "User-Agent", "value": "curl/7.66.0" }],
"accept": [{ "key": "accept", "value": "*/*" }]
},
"method": "GET",
"querystring": "",
"uri": "/"
}
}
}
]
}
(1) Lambda 関数を Lambe@Edge にデプロイする
5. CloudFront に Lambda@Edge をデプロイする
Lambda 関数のページから “アクション” > “Lambda@Edge へのデプロイ” に進む
(1) Lambda 関数を Lambe@Edge にデプロイする
5. CloudFront に Lambda@Edge をデプロイする
キャッシュ動作には “ *” を、“ CloudFront イベント” には ”ビューワーリクエスト” を設定する
“ ボディを含める” “ Lambda@Edge へのデプロイを確認” にチェックを入れて “デプロイ” を押す
(2) Cognito のコールバック URL を更新する
5. CloudFront に Lambda@Edge をデプロイする
Cognito のアプリケーションクライアントから ”ログインページ” タブを開き、”マネージドログ
インページ” の “許可されているコールバック URL” に CloudFront のドメインを設定する
(3) 動作確認
5. CloudFront に Lambda@Edge をデプロイする
“https://< ディストリビューションドメイン >/index.html” にアクセスし、メールアドレスとパ
スワードを入力すると “ index.html” にアクセスできることを確認する
無料枠と料金について
付録①
サービス 無料利用枠 料金例
Amazon S3
毎月 5GB の標準ストレージ、 20,000
件の GET リクエスト、 2,000 件の PUT
リクエストが無料
標準ストレージ: 1GB あたり月額約
0.023 USD
CloudFront
毎月 1TB のデータ転送、 1,000,000 件
の HTTP/HTTPS リクエストが無料
データ転送:最初の 10TB まで 1GB あ
たり 0.085 USD
Lambda@Edge
毎月 1,000,000 件のリクエス
ト、 400,000 GB 秒のコンピューティ
ング時間が無料
無料枠超過時は、リクエスト数とコン
ピューティング時間に応じて課金
(例: 1GB 秒あたり 0.00001667
USD )
Cognito
毎月 50,000 人のアクティブユーザー
( MAU )が無料
50,001 ~ 100,000 人の MAU に対して、
1MAU あたり 0.0055 USD
CloudWatch
10 カスタムメトリクス、 10 アラーム、
5GB のログデータ取り込み、 3 ダッ
シュボードが無料
追加メトリクス: 1 メトリクスあたり
月額 0.30 USD
本ドキュメントで使用したサービスはすべて無料利用枠を提供しており、構築するだけであれば
ほとんどコストをかけずに実施可能
他の方式との比較
付録②
方式 実装工数 セキュリティ 管理工数
パスワードをかけた
ファイルをメール配信
AWS の設定不要
パスワードが流出しな
ければファイルを開け
ない
ユーザーごとにメール
送信が必要
S3 署名付き URL を配布
( 参考)
実装不要
有効期限があるため流
出時のリスクが小さい
有効期限が切れるたび
に URL の生成が必要
Cognito を紐づけた API
Gateway から Lambda
を起動し署名付き URL
を生成する ( 参考)
認証トークンを取得す
るための UI の実装が
必要
認証が突破されなけれ
ばファイルは流出しな
い
ユーザーの管理やアク
セス権の付与が簡便
CloudFront に Cognito
による認証を実装する
( 本ドキュメントで紹
介 )
SDKを利用することで
比較的簡便に実装可能
認証が突破されなけれ
ばファイルは流出しな
い
ユーザーの管理やアク
セス権の付与が簡便
本ドキュメントで紹介した方法以外にもファイル配布をセキュアに実施可能な方法はあるが、本
ドキュメントで説明した方式が最も簡便かつ安全
Ad

More Related Content

Similar to AWSにアップロードしたファイルに認証をつける(CloudFront+Lambda@Edge) (20)

[Cloud OnAir] Google Cloud でセキュアにアプリケーションを開発しよう 2019年3月7日 放送
[Cloud OnAir] Google Cloud でセキュアにアプリケーションを開発しよう 2019年3月7日 放送[Cloud OnAir] Google Cloud でセキュアにアプリケーションを開発しよう 2019年3月7日 放送
[Cloud OnAir] Google Cloud でセキュアにアプリケーションを開発しよう 2019年3月7日 放送
Google Cloud Platform - Japan
 
20120201 aws meister-reloaded-iam-and-billing-public
20120201 aws meister-reloaded-iam-and-billing-public20120201 aws meister-reloaded-iam-and-billing-public
20120201 aws meister-reloaded-iam-and-billing-public
Amazon Web Services Japan
 
AAD authentication for azure app v0.1.20.0317
AAD authentication for azure app v0.1.20.0317AAD authentication for azure app v0.1.20.0317
AAD authentication for azure app v0.1.20.0317
Ayumu Inaba
 
初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣
Yuji Takayama
 
Cm re growth-reinvent-app304-kaji
Cm re growth-reinvent-app304-kajiCm re growth-reinvent-app304-kaji
Cm re growth-reinvent-app304-kaji
Hiroyuki Kaji
 
AWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch Logs
AWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch LogsAWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch Logs
AWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch Logs
Amazon Web Services Japan
 
Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編
なべ
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライ
Masanobu Sato
 
BCPに活かせ!一撃 CloudFormation
BCPに活かせ!一撃 CloudFormationBCPに活かせ!一撃 CloudFormation
BCPに活かせ!一撃 CloudFormation
真吾 吉田
 
Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積
Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積
Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積
Takeshi Mikami
 
20120528 aws meister-reloaded-awssd-kforjava-public
20120528 aws meister-reloaded-awssd-kforjava-public20120528 aws meister-reloaded-awssd-kforjava-public
20120528 aws meister-reloaded-awssd-kforjava-public
Amazon Web Services Japan
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...
Shotaro Suzuki
 
G0042 h
G0042 hG0042 h
G0042 h
silicone69
 
Scale Your Business without Servers
Scale Your Business without ServersScale Your Business without Servers
Scale Your Business without Servers
Keisuke Nishitani
 
Azure Arc Jumpstart Update - HCIBox Edition
Azure Arc Jumpstart Update - HCIBox EditionAzure Arc Jumpstart Update - HCIBox Edition
Azure Arc Jumpstart Update - HCIBox Edition
Kazuki Takai
 
AWS Black Belt Tech シリーズ 2015 - AWS IoT
AWS Black Belt Tech シリーズ 2015 - AWS IoTAWS Black Belt Tech シリーズ 2015 - AWS IoT
AWS Black Belt Tech シリーズ 2015 - AWS IoT
Amazon Web Services Japan
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom Vision
Yoshitaka Seo
 
AWS Black Belt Online Seminar 2017 AWS Cognito
AWS Black Belt Online Seminar 2017 AWS CognitoAWS Black Belt Online Seminar 2017 AWS Cognito
AWS Black Belt Online Seminar 2017 AWS Cognito
Amazon Web Services Japan
 
20200630 AWS Black Belt Online Seminar Amazon Cognito
20200630 AWS Black Belt Online Seminar Amazon Cognito20200630 AWS Black Belt Online Seminar Amazon Cognito
20200630 AWS Black Belt Online Seminar Amazon Cognito
Amazon Web Services Japan
 
[Cloud OnAir] Cloud Run Deep Dive ~ GCP で実践するモダンなサーバーレス アプリケーション開発 ~ 2019年9月...
[Cloud OnAir] Cloud Run Deep Dive  ~ GCP で実践するモダンなサーバーレス アプリケーション開発 ~ 2019年9月...[Cloud OnAir] Cloud Run Deep Dive  ~ GCP で実践するモダンなサーバーレス アプリケーション開発 ~ 2019年9月...
[Cloud OnAir] Cloud Run Deep Dive ~ GCP で実践するモダンなサーバーレス アプリケーション開発 ~ 2019年9月...
Google Cloud Platform - Japan
 
[Cloud OnAir] Google Cloud でセキュアにアプリケーションを開発しよう 2019年3月7日 放送
[Cloud OnAir] Google Cloud でセキュアにアプリケーションを開発しよう 2019年3月7日 放送[Cloud OnAir] Google Cloud でセキュアにアプリケーションを開発しよう 2019年3月7日 放送
[Cloud OnAir] Google Cloud でセキュアにアプリケーションを開発しよう 2019年3月7日 放送
Google Cloud Platform - Japan
 
20120201 aws meister-reloaded-iam-and-billing-public
20120201 aws meister-reloaded-iam-and-billing-public20120201 aws meister-reloaded-iam-and-billing-public
20120201 aws meister-reloaded-iam-and-billing-public
Amazon Web Services Japan
 
AAD authentication for azure app v0.1.20.0317
AAD authentication for azure app v0.1.20.0317AAD authentication for azure app v0.1.20.0317
AAD authentication for azure app v0.1.20.0317
Ayumu Inaba
 
初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣
Yuji Takayama
 
Cm re growth-reinvent-app304-kaji
Cm re growth-reinvent-app304-kajiCm re growth-reinvent-app304-kaji
Cm re growth-reinvent-app304-kaji
Hiroyuki Kaji
 
AWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch Logs
AWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch LogsAWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch Logs
AWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch Logs
Amazon Web Services Japan
 
Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編
なべ
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライ
Masanobu Sato
 
BCPに活かせ!一撃 CloudFormation
BCPに活かせ!一撃 CloudFormationBCPに活かせ!一撃 CloudFormation
BCPに活かせ!一撃 CloudFormation
真吾 吉田
 
Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積
Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積
Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積
Takeshi Mikami
 
20120528 aws meister-reloaded-awssd-kforjava-public
20120528 aws meister-reloaded-awssd-kforjava-public20120528 aws meister-reloaded-awssd-kforjava-public
20120528 aws meister-reloaded-awssd-kforjava-public
Amazon Web Services Japan
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...
Shotaro Suzuki
 
Scale Your Business without Servers
Scale Your Business without ServersScale Your Business without Servers
Scale Your Business without Servers
Keisuke Nishitani
 
Azure Arc Jumpstart Update - HCIBox Edition
Azure Arc Jumpstart Update - HCIBox EditionAzure Arc Jumpstart Update - HCIBox Edition
Azure Arc Jumpstart Update - HCIBox Edition
Kazuki Takai
 
AWS Black Belt Tech シリーズ 2015 - AWS IoT
AWS Black Belt Tech シリーズ 2015 - AWS IoTAWS Black Belt Tech シリーズ 2015 - AWS IoT
AWS Black Belt Tech シリーズ 2015 - AWS IoT
Amazon Web Services Japan
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom Vision
Yoshitaka Seo
 
AWS Black Belt Online Seminar 2017 AWS Cognito
AWS Black Belt Online Seminar 2017 AWS CognitoAWS Black Belt Online Seminar 2017 AWS Cognito
AWS Black Belt Online Seminar 2017 AWS Cognito
Amazon Web Services Japan
 
20200630 AWS Black Belt Online Seminar Amazon Cognito
20200630 AWS Black Belt Online Seminar Amazon Cognito20200630 AWS Black Belt Online Seminar Amazon Cognito
20200630 AWS Black Belt Online Seminar Amazon Cognito
Amazon Web Services Japan
 
[Cloud OnAir] Cloud Run Deep Dive ~ GCP で実践するモダンなサーバーレス アプリケーション開発 ~ 2019年9月...
[Cloud OnAir] Cloud Run Deep Dive  ~ GCP で実践するモダンなサーバーレス アプリケーション開発 ~ 2019年9月...[Cloud OnAir] Cloud Run Deep Dive  ~ GCP で実践するモダンなサーバーレス アプリケーション開発 ~ 2019年9月...
[Cloud OnAir] Cloud Run Deep Dive ~ GCP で実践するモダンなサーバーレス アプリケーション開発 ~ 2019年9月...
Google Cloud Platform - Japan
 

AWSにアップロードしたファイルに認証をつける(CloudFront+Lambda@Edge)

  • 2. 目次  本ドキュメントの目的  システム構成  使用するサービス一覧  システム全体像  処理フロー  構築手順 1. S3のバケットにファイルをアップロードする 2. CloudFrontを作成しS3バケットをオリジンに設定する 3. Cognitoユーザープールを設定する 4. 認証処理用のLambda関数を実装しデプロイする 5. CloudFrontにLambda@Edgeをデプロイする  付録  無料枠と料金について  他の方式との比較
  • 3. 本ドキュメントの目的 • AWS のサービスを組み合わせることで、認証されたユーザーだけがファイル にアクセスできるような仕組みを構築することができます 背景 解決策 本ドキュメン トの目的 • ユーザーに対してファイルを配信したいが、制限されたユーザーだけがアク セスできるようにしたい ( アクセスできるユーザーを制御したい ) • ファイル保存先の URL が流出しても、第三者が不正にアクセスできないよう にしたい • クラウドにアップロードしたファイルに認証をつけるためのシステム構成と 構築手順について説明します アクセスを許可したユー ザー その他のユーザー
  • 4. 使用するサービス一覧 システム構成 サービス名 アイコン 機能 Amazon Simple Storage Service (Amazon S3) • 画像、動画などのファイルをクラウド上に保存できる ストレージサービス Amazon CloudFront • コンテンツ配信サービス • S3 に保存したファイルを全世界に高速で配信するこ とができる • S3 と組み合わせてセキュリティの向上やその他の追 加機能を実装することができる AWS Lambda • ユーザーからリクエストがあった時だけ起動して処理 を実行する • Lambda@Edge: ユーザーが CloudFront にアクセスし た際に特定の処理を実行できる Amazon Cognito • ユーザー管理サービス • ログイン機能を簡便に追加できる • パスワード認証や、 Google/Facebook ログインなど を設定することもできる Amazon CloudWatch • AWS で使用している各サービスのログを監視できる
  • 5. システム全体像 システム構成 AWS Cloud AWS Lambda Amazon Simple Storage Service (Amazon S3) Amazon CloudFront Amazon Cognito Amazon CloudWatch 認証されていないユーザーからのアクセ スは拒否 ログ出 力 認証処理実行 アクセス時に Lambda@Edge 実行 Cognito の認証済ユーザーだけアクセス許可 index.html cat.jpg
  • 8. (1) バケットを作成する 1. S3 のバケットにファイルをアップロードする S3 の画面から ”バケットを作成” ボタンを押す。すべてデフォルト設定でバケットを作成する デフォルト設定ではパブリックアクセスはすべてブロックされる
  • 9. (2) バケットにファイルをアップロードする 1. S3 のバケットにファイルをアップロードする バケットの画面から “アップロード” を押し、ファイルを選択してアップロードする
  • 10. (3) 動作確認 1. S3 のバケットにファイルをアップロードする アップロード後、オブジェクト URL にアクセスすると “ Access Denied” になっていることを確 認する
  • 11. 作業後の状態 1. S3 のバケットにファイルをアップロードする AWS Cloud AWS Lambda Amazon Simple Storage Service (Amazon S3) Amazon CloudFront Amazon Cognito Amazon CloudWatch 認証されていないユーザーからのアクセ スは拒否 ログ出 力 認証処理実行 アクセス時に Lambda@Edge 実行 Cognito の認証済ユーザーだけアクセス許可 index.html cat.jpg パブリックアクセスを ブロックしているため どの経路でもアクセス できない
  • 12. (1) ディストリビューションを作成する 2. CloudFront を作成し S3 バケットをオリジンに設定する CloudFront から “ディストリビューションを作成” に進む “ オリジン” セクションで作成したバケット名を選択する。オリジンアクセスで “ Origin access control settings” を設定
  • 13. (2) Origin Access Control の設定 2. CloudFront を作成し S3 バケットをオリジンに設定する すべてデフォルト設定で作成する Origin Access Control(OAC) • CloudFront のオリジンへの直接アクセスを制限する • 今回は CloudFront で認証処理を設定するため、 CloudFront 経由のアクセスに制限すること で認証が必ず実行されるようにする
  • 14. (3) バケットポリシーの更新 2. CloudFront を作成し S3 バケットをオリジンに設定する バケットの設定画面から “アクセス許可” > “ バケットポリシー” に進み、”編集” を押す
  • 15. (3) バケットポリシーの更新 2. CloudFront を作成し S3 バケットをオリジンに設定する バケットポリシーの編集画面で下記のポリシーを設定 { "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::static-site-auth-testing/*", "Condition": { "StringEquals": { “AWS:SourceArn”: “< 作成したディストリビューションの ARN>" } } } ] }
  • 16. (4) 動作確認 2. CloudFront を作成し S3 バケットをオリジンに設定する “ 一般” タブからディストリビューションドメイン名をコピーし、末尾に /index.html を付与した URL でアクセスできることを確認する
  • 17. 作業後の状態 2. CloudFront を作成し S3 バケットをオリジンに設定する AWS Cloud AWS Lambda Amazon Simple Storage Service (Amazon S3) Amazon CloudFront Amazon Cognito Amazon CloudWatch 認証されていないユーザーからのアクセ スは拒否 ログ出 力 認証処理実行 アクセス時に Lambda@Edge 実行 Cognito の認証済ユーザーだけアクセス許可 index.html cat.jpg CloudFront 経由のア クセスだけが許可され ている 認証処理は未実装のた め、すべてのユーザー がアクセスできる
  • 18. (1) ユーザープールを作成する 3. Cognito ユーザープールを設定する “Amazon Cognito” > “ ユーザープール” からユーザープール作成に進む
  • 19. (2) アプリケーションの定義 3. Cognito ユーザープールを設定する サインイン識別子はメールアドレスに設定して ”作成” を押す
  • 20. (3) テスト用ユーザーを作成する 3. Cognito ユーザープールを設定する “ ユーザー” タブからテスト用のユーザーを作成する。仮パスワードセクションは ”パスワードの 生成” を選択
  • 21. (4) テスト用ユーザーでログインする 3. Cognito ユーザープールを設定する ユーザー作成後に下記のようなメールで仮パスワードが通知されることを確認する “ アプリケーションクライアント” から登録したアプリケーションを開き、”ログインページを表 示” をクリックする
  • 22. (4) テスト用ユーザーでログインする 3. Cognito ユーザープールを設定する 仮パスワードでログイン後、パスワードを更新してログインページに入れることを確認する
  • 23. (1) Lambda 関数の実装 4. 認証処理用の Lambda 関数を実装しデプロイする 下記コマンドで npm プロジェクトを初期化する $ mkdir lambda-at-edge # 作業用ディレクトリ作成 $ npm init # npm プロジェクト初期化 $ touch index.js # index.js ファイル作成 $ npm install cognito-at-edge # ライブラリインストール const { Authenticator } = require("cognito-at-edge"); const authenticator = new Authenticator({ region: "< 認証に使用するユーザープールを作成したリージョン >", userPoolId: "< ユーザープール ID>", userPoolAppId: "< クライアント ID>, userPoolAppSecret: "< クライアントシークレット >", userPoolDomain: "< ユーザープールのドメイン >", }); exports.handler = async (request) => authenticator.handle(request); index.js に以下のコードを追加 CloudFront にデプロイする Lambda@Edge はサイズ制限がある ( ビューワーリクエストに紐づけ る場合は 1MB) 下記コマンドでバンドルすることでサイズを圧縮してから、 ZIP ファイルを作成する $ npx esbuild --bundle index.js --minify --outfile=bundle.js --platform=node # バン ドル $ zip bundle.zip bundle.js # Lambda にアップロードするために ZIP ファイル作成
  • 24. (2) Lambda 関数の作成 4. 認証処理用の Lambda 関数を実装しデプロイする バージニア北部 (us-east-1) で関数を作成する “ 実行ロール” セクションで、ポリシーテンプレートから ”基本的な Lambda@Edge のアクセス権 限” を選択し、新しいロールを作成して設定する
  • 25. (3) Lambda 関数のデプロイ 4. 認証処理用の Lambda 関数を実装しデプロイする Lambda 関数の画面から “アップロード元” > “.zip ファイル” を選択しバンドルしたファイルから 作成した ZIP ファイルをアップロードする
  • 26. (3) Lambda 関数のデプロイ 4. 認証処理用の Lambda 関数を実装しデプロイする “ ランタイム設定” からハンドラを “ bundle.handler” に更新する
  • 27. (3) Lambda 関数のテスト 4. 認証処理用の Lambda 関数を実装しデプロイする “ イベント JSON” に以下の JSON を入力して実行し、正常終了することを確認する { "Records": [ { "cf": { "config": { "distributionDomainName": "d111111abcdef8.cloudfront.net", "distributionId": "EDFDVBD6EXAMPLE", "eventType": "viewer-request", "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ==" }, "request": { "clientIp": "203.0.113.178", "headers": { "host": [ { "key": "Host", "value": "d111111abcdef8.cloudfront.net" } ], "user-agent": [{ "key": "User-Agent", "value": "curl/7.66.0" }], "accept": [{ "key": "accept", "value": "*/*" }] }, "method": "GET", "querystring": "", "uri": "/" } } } ] }
  • 28. (1) Lambda 関数を Lambe@Edge にデプロイする 5. CloudFront に Lambda@Edge をデプロイする Lambda 関数のページから “アクション” > “Lambda@Edge へのデプロイ” に進む
  • 29. (1) Lambda 関数を Lambe@Edge にデプロイする 5. CloudFront に Lambda@Edge をデプロイする キャッシュ動作には “ *” を、“ CloudFront イベント” には ”ビューワーリクエスト” を設定する “ ボディを含める” “ Lambda@Edge へのデプロイを確認” にチェックを入れて “デプロイ” を押す
  • 30. (2) Cognito のコールバック URL を更新する 5. CloudFront に Lambda@Edge をデプロイする Cognito のアプリケーションクライアントから ”ログインページ” タブを開き、”マネージドログ インページ” の “許可されているコールバック URL” に CloudFront のドメインを設定する
  • 31. (3) 動作確認 5. CloudFront に Lambda@Edge をデプロイする “https://< ディストリビューションドメイン >/index.html” にアクセスし、メールアドレスとパ スワードを入力すると “ index.html” にアクセスできることを確認する
  • 32. 無料枠と料金について 付録① サービス 無料利用枠 料金例 Amazon S3 毎月 5GB の標準ストレージ、 20,000 件の GET リクエスト、 2,000 件の PUT リクエストが無料 標準ストレージ: 1GB あたり月額約 0.023 USD CloudFront 毎月 1TB のデータ転送、 1,000,000 件 の HTTP/HTTPS リクエストが無料 データ転送:最初の 10TB まで 1GB あ たり 0.085 USD Lambda@Edge 毎月 1,000,000 件のリクエス ト、 400,000 GB 秒のコンピューティ ング時間が無料 無料枠超過時は、リクエスト数とコン ピューティング時間に応じて課金 (例: 1GB 秒あたり 0.00001667 USD ) Cognito 毎月 50,000 人のアクティブユーザー ( MAU )が無料 50,001 ~ 100,000 人の MAU に対して、 1MAU あたり 0.0055 USD CloudWatch 10 カスタムメトリクス、 10 アラーム、 5GB のログデータ取り込み、 3 ダッ シュボードが無料 追加メトリクス: 1 メトリクスあたり 月額 0.30 USD 本ドキュメントで使用したサービスはすべて無料利用枠を提供しており、構築するだけであれば ほとんどコストをかけずに実施可能
  • 33. 他の方式との比較 付録② 方式 実装工数 セキュリティ 管理工数 パスワードをかけた ファイルをメール配信 AWS の設定不要 パスワードが流出しな ければファイルを開け ない ユーザーごとにメール 送信が必要 S3 署名付き URL を配布 ( 参考) 実装不要 有効期限があるため流 出時のリスクが小さい 有効期限が切れるたび に URL の生成が必要 Cognito を紐づけた API Gateway から Lambda を起動し署名付き URL を生成する ( 参考) 認証トークンを取得す るための UI の実装が 必要 認証が突破されなけれ ばファイルは流出しな い ユーザーの管理やアク セス権の付与が簡便 CloudFront に Cognito による認証を実装する ( 本ドキュメントで紹 介 ) SDKを利用することで 比較的簡便に実装可能 認証が突破されなけれ ばファイルは流出しな い ユーザーの管理やアク セス権の付与が簡便 本ドキュメントで紹介した方法以外にもファイル配布をセキュアに実施可能な方法はあるが、本 ドキュメントで説明した方式が最も簡便かつ安全
  翻译: