AWS S3で公開している静的サイトにBasic認証をかける方法です。
S3の他に、LambdaとCloudFrontの設定が必要になります。
S3バケットの作成
まずはBasic認証をかけたいS3のバケットを用意します。
パブリックアクセスの許可や、Static website hostingの設定は必要ありません。
CloudFrontの設定
Create distribution -> Web側のGet Startedを選択し、CloudFrontの設定に進みます。
Origin Domain Name にBasic認証をかけたいS3のバケットを指定します。
Origin ID は自動的に設定されます。
Restrict Bucket Access を Yes にします。
Origin Access Identity は Create a New Identity にします。
これで Comment 部分は自動で設定されます。
Grant Read Permissions on Bucket は Yes, Update Bucket Policy を選択してください。
キャッシュは無効にするので、 Cache Policy は Managed-CachingDisabled を選択してください。
Default Root Object を index.html 等に設定すれば、ルートにアクセスした際のデフォルトファイルを指定可能です。
その他はデフォルト設定でOKです。
ここまで設定したら、Create Distributionを押して作成しましょう。
デプロイが完了したら、指定したS3のバケットポリシーに設定が追加されていることがわかります。

また、 CloudFrontの Error Pages の設定で、 403 404 エラーの際は /index.html へリダイレクトするように設定しておきましょう。
この設定がなければ、SPAのサイトではルート以外のURL(例えば /about など)で画面を更新した際にエラーになってしまいます。
Lambdaの設定
Basic認証を行うためのLambda関数を作成します。
バージニア北部(us-east-1) から作成を行ってください。
関数名 は basicAuthentication としています。
ランタイム は Node.js です。
デフォルトの実行ロールの変更 では、 AWSポリシーテンプレートから新しいロールを作成 を選択し、
ロール名 に lambda_edge_exec (任意の名前)、 ポリシーテンプレート - オプション に 基本的な Lambda@Edge のアクセス権限 (CloudFront トリガーの場合 を設定します。
関数コードの index.js に下記のコードを貼り付けます。
const authUser = 'user'; と const authPass = 'pass'; の部分で、Basic認証のuserとpassを設定します。
その後 Deploy ボタンを押してデプロイします。
'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);
};
アクション -> Lambda@Edgeへのデプロイ を選択します。
ディストリビューション に先程作成したCloudFrontを指定します。
CloudFrontイベント は ビューアーリクエスト を選択します。
Lambda@Edgeへのデプロイを確認 にチェックして、デプロイを行います。
CloudFrontを確認すると、 status が In Progress になっていることが確認できます。
デプロイが完了すると、CloudFrontのドメインネームにアクセスした際、Basic認証がかけられていることが確認できます。
ちなみに、 バージニア北部(us-east-1) 以外で作ったばかりのS3のバケットにCloudFront経由でアクセスしても、リダイレクトされてしまいます。
しばらく待つか、下記の解決法を参考にしてください。
S3+CloudFrontでS3のURLにリダイレクトされてしまう場合の対処法









