Edited at

CloudfrontとS3でBasic認証をかける

More than 1 year has passed since last update.


S3 bucketの作成

まずはhtmlファイル等を格納するS3のbucketを作成します。

Cloudfrontから配信するのでパブリックアクセス許可やStatic website hostingの設定は不要です。


lambda関数の作成

次にBasic認証を処理するlambda関数を作成します。

この時、右上のリージョン設定で「バージニア北部」を選択してから「関数の作成」をしてください。

スクリーンショット 2018-02-07 14.31.16.png

名前に"BasicAuthentication"(任意の名前)

ランタイムはNode.js 6.10を選択

ロールは"テンプレートから新しいロールを作成"を選択

ロール名には"lambda_edge_exection"(任意の名前)

ポリシーテンプレートは"Basic Edge Lambdaアクセス権限"を選択

関数の作成をクリックしてしばらくすると次の画面に切り替わります。


スクリーンショット 2018-02-07 14.33.43.png

少しスクロールしたところの「関数コード」のエリアに以下のコードをコピペします。

9行目、10行目のauthUser、authPassでBasic認証のログイン用のIDとパスワードが設定できます。

https://gist.github.com/lmakarov/e5984ec16a76548ff2b278c06027f1a4


lambda-basic-auth.js

'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);
};


入力後、右上の「保存」ボタンをクリックして保存します。


スクリーンショット 2018-02-07 14.37.04.png

その後、「アクション」メニューから「新しいバージョンを発行」を選択します。

出てきたポップアップの「発行」をクリックするとバージョン1として保存されます。


スクリーンショット 2018-02-07 14.39.57.png

保存されたら、右上に表示されているARNの値をコピーしておきます。

例)

arn:aws:lambda:us-east-1:xxxxxxxxxxxx:function:BasicAuthentication:1


Cloudfrontの作成

次にCloudfrontのdistributionを作成します。

スクリーンショット 2018-02-07 11.46.08.png

Webの方の"Get Started"をクリックします。


スクリーンショット 2018-02-07 14.04.13.png

Origin Settings

Origin Domain Nameのところに先ほど作成したS3のbucketを選択します。

Restrict Bucket AccessをYes

Origin Access IdentityをCreate a New Identity

Grant Read Permissions on BucketをYes, Update Bucket Policy

とすることで該当のbucketのPolicyがCloudfrontから読み取りできるように設定されます。


スクリーンショット 2018-02-07 14.47.55.png

Default Cache Behavior Settings

Object Cachingを"Customize"にして

各TTLを0にすることでキャッシュされないようになるので、テスト環境の構築時には便利です。

そして、今回の設定のポイントである「Lambda Function Associations」の部分に

Event Typeに"Viewer Request"を選択

Lambda Function ARNに先ほどコピーしたARNをペーストします。

Distribution Settingsのところで

Default Root Objectに"index.html"

と設定しておくことでroot URL(ドメイン+/で終わるURL)でアクセスした時のデフォルトファイルを設定できます。

最後に右下の「Create Distoribution」をクリックして完了を待ちます。


ここまででも使えるのですが、デフォルトの設定でエラーキャッシュが効いてしまうのでそれを無効にしておきます。

作成したDistoributionを選択して、「Error Pages」のタブで「Create Custom Error Response」をクリックします。


スクリーンショット 2018-02-07 15.01.22.png

403エラー時のTTLを0に設定


スクリーンショット 2018-02-07 15.04.33.png

angular等のSPAでのルーティングをうまく利用するために404エラーはindex.htmlを開く、のようにしたい場合は

Custom Error ResponseをYes

にすることで設定可能です。

(Response Page Pathは / から始まる必要があります。)


Basic認証を外すとき

Distoributionの「Behaviors」タブから設定されているBehaviorを選択し、Editをクリックします。

スクリーンショット 2018-02-07 15.16.09.png

Lambda Function Associationsにあるlambda functionの右のXをクリックして削除します。

右下の「Yes, Edit」をクリックします。

しばらくすると設定が反映されます。


参考にしたURL

https://hackernoon.com/serverless-password-protecting-a-static-website-in-an-aws-s3-bucket-bfaaa01b8666

http://blog.jicoman.info/2017/10/s3-basic-using-cloudfront-lambda-edge/