初学者のためのAWS入門シリーズ
- [初学者のためのAWS入門(1)] (https://qiita.com/mshinoda88/items/e7557227f7060b52d8ae)
- 初学者のためのAWS入門(2) - CloudFormation入門1
- 初学者のためのAWS入門(3) - CloudFormation入門2
- 初学者のためのAWS入門(4) - S3でBasic認証を設定してリポジトリを公開 -> この記事です。
- 初学者のためのAWS入門(5) - S3+Athena+QuickSightでデータ分析結果の可視化
- 初学者のためのAWS入門(6) - Lambdaでサーバレス実行してみる
S3を外部にWeb公開する際に、認証設定してみます。
S3自体にBasic認証機能は提供されていませんので、Lambda@Edgeという機能を使うことで、サーバレスにBasic認証をかけることができます。
作業概要
Lambda@Edge とは
CloudFrontのイベントに対してLambda関数を実行できる機能。Lambda@Edgeが実行できるCloudFrontのイベントは、以下の4つがあります。
- CloudFrontがエンドユーザからHTTPリクエストを受信(ビューワーリクエスト)
- CloudFrontが受け取ったHTTPリクエストをオリジンサーバに転送する前(オリジンリクエスト)
- CloudFrontがオリジンサーバからレスポンスを受信(オリジンレスポンス)
- CloudFrontがエンドユーザにレスポンスを返す前(ビューワーレスポンス)
Lambda@Edge のユースケースとして以下の用途がドキュメントに書かれていました(一部抜粋)。
A/B テスト用に、異なるバージョンのサイトに URL を書き換えるために Cookie を検査します
リクエストを送信したデバイスに関する情報が含まれている、User-Agent ヘッダーに基づいてユーザーにさまざまなオブジェクトを送信します。たとえば、ユーザーのデバイスに応じて、さまざまな解像度のイメージをユーザーに送信できます。
ヘッダーまたは認証トークンを検査し、対応するヘッダーを挿入して、リクエストをオリジンに転送する前にアクセス制御を有効にします。
ヘッダーの追加、削除、変更、および URL パスの書き換えを行い、キャッシュの異なるオブジェクトにユーザーをダイレクトします。
未認証ユーザーをログインページにリダイレクトしたり、エッジから直に静的ウェブページを作成して配信したりといったことを行う新しい HTTP レスポンスを生成します。
[AWS Lambda@Edge - AWS Lambda] (http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-edge.html)
サービス構成
以下のサービスを組み合わせて実現させます。
S3
- 取りに行きたいファイルを置く
CloudFront
- Lambda@Edgeとの連携
- キャッシュ、TTLは無効化する
Lambda@Edge
- Basic認証を設定(Authorizationヘッダを追加する)
作業の流れ
- 公開するS3のバケットを作成
- Basic認証を処理するlambda関数を作成
- Cloudfrontの作成
- Cloudfrontの設定
- 公開ページにアクセスして確認
1. 公開するS3のバケットを作成
2. Basic認証を処理するlambda関数を作成
右上のリージョン設定で「バージニア北部」を選択してから「関数の作成」をすること。そうしないと、
のようなエラーになり、失敗します。
「一から作成」を選択。関数名として任意の名前を入力。ここでは「BasicAuthentication_bw_data」
ロールは「テンプレートから新しいロールを作成」を選択
ロール名には任意の名前を入力。ここでは「role_s3_read」
ポリシーテンプレートは「基本的なLambda@Edgeのアクセス権限(CloudFrontトリガーの場合)」を選択
「関数の作成」をクリックしてしばらくすると次の画面に切り替わります。
関数入力欄に以下をコピー。
https://gist.github.com/lmakarov/e5984ec16a76548ff2b278c06027f1a4
'use strict';
exports.handler = (event, context, callback) => {
// Get request and request headers
const request = event.Records[0].cf.request;
const headers = request.headers;
// Configure authentication
const authUser = 'user';
const authPass = 'pass';
// Construct the Basic Auth string
const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64');
// Require Basic authentication
if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
const body = 'Unauthorized';
const response = {
status: '401',
statusDescription: 'Unauthorized',
body: body,
headers: {
'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
},
};
callback(null, response);
}
// Continue request processing if authentication passed
callback(null, request);
};
以下の部分がBasic認証のユーザとパスワード部になります。
// Configure authentication
const authUser = 'user';
const authPass = 'pass';
任意の説明を記入して、「発行」→これでCloudFrontから参照できるようになった。
右上のARNをコピーして記録しておく。後ほどCloudFrontから参照する際にこのARNをペーストすることになる。
3. Cloudfrontの作成
Origin Settins
Origin Domain Names
プルダウンから選択。
Restrict Bucket Access
「Yes」を選択
Origin Access Identity
「Create a New Identity」を選択
Grant Read Permission on Bucket
「Yes, Update Bucket Policy」を選択
Default Cache Behavior Settings
Object Caching
「Customize」にして
各TTLを0にすることでキャッシュされないようになるので、テスト環境の構築時には便利。
Lambda Function Associations
「CloudFront Event」を「Viewer Request」を選択。
「Lambda Function ARN」に先ほどコピーしたARNをペーストする。
Distribution Settings
Default Root Object
「index.html」と設定しておくことでroot URL(ドメイン+/で終わるURL)でアクセスした時のデフォルトファイルを設定できる。
最後に右下の「Create Distoribution」をクリックして完了を待ちます。
CloudFrontの「Distribution」を選択し、状態を確認する。
状態が「In Progress」から「Deployed」になったら完了。
4. Cloudfrontの設定
デフォルトの設定でエラーキャッシュが効いてしまうのでそれを無効にしておく。
作成したDistoributionを選択して、「Error Pages」のタブを選択。
「Create Custom Error Response」をクリック。
404エラーはindex.htmlを開く、のようにしたい場合は
Custom Error ResponseをYesにすることで設定可能です。
(Response Page Pathは / から始まる必要があります。)
公開ページにアクセスして確認
公開されるドメインはここで確認できる。http://XXX.cloudfront.net