目的
取り急ぎCloudFront経由でのアプリケーションへのアクセスをするために、最低限の認証機能を実装する方法を試しました。
初学者のため、内容に誤りや適切ではない情報があればご指摘いただけると嬉しいです。
概要
Basic認証をCloudFrontの機能で実装することができます。
手順
※CloudFrontとオリジンは作成済み・設定済みの想定です。
参考:https://qiita.com/hirotaka_s/items/41bdaedb07376798089b
1. 認証情報の作成
Base64で認証情報を作成します。
下記はユーザー名「admin」で、パスワード「Very-Strong-Pass!」とする場合のサンプルです。
echo -n 'admin:Very-Strong-Pass!' | base64
2. 認証に使うコードを作成
functions.jsファイルを、AWSCLIを実行している環境に作成します。
※2行目の$Base64_Codeを、手順1で実行した結果に置き換えてください。
var REALM = 'edge-basic';
var EXPECTED = 'Basic $Base64_Code';
var BYPASS_PATHS = ['/healthz'];
function unauthorized() {
return {
statusCode: 401,
statusDescription: 'Unauthorized',
headers: {
'www-authenticate': { value: 'Basic realm="'+ REALM +'"' },
'cache-control': { value: 'no-store' },
'content-type': { value: 'text/plain; charset=utf-8' }
},
body: 'Unauthorized'
};
}
function handler(event) {
var req = event.request;
var uri = req.uri || '/';
for (var i=0;i<BYPASS_PATHS.length;i++){
if (uri.indexOf(BYPASS_PATHS[i]) === 0) return req;
}
if ((req.method || 'GET').toUpperCase() === 'OPTIONS') return req;
var auth = (req.headers.authorization || {}).value || '';
if (auth !== EXPECTED) return unauthorized();
if (req.headers.authorization) {
delete req.headers.authorization;
}
return req;
}
3. CloudFrontで関数の作成
作成したコードから、CloudFrontの関数を作成する。
aws cloudfront create-function \
--name edge-basic-auth \
--function-config '{"Comment":"Basic Auth Function","Runtime":"cloudfront-js-1.0"}' \
--function-code fileb://function.js
4. 作成した関数の公開
※$Function_ETAGを、手順3を実行した結果のETAGの値に置き換えてください。
aws cloudfront publish-function \
--name edge-basic-auth \
--if-match $Function_ETAG
5. 関数とDistributionの関連付け
Distributionの設定内容とそのETAGの値、作成した関数のARNを変数に格納します。
※$DIST_IDは作成済みのDistributionのIDに置き換えてください。
FN_ARN=$(aws cloudfront describe-function --name edge-basic-auth --query 'FunctionSummary.FunctionMetadata.FunctionARN' --output text)
DIST_DATA=$(aws cloudfront get-distribution-config --id $DIST_ID)
DIST_ETAG=$(echo $DIST_DATA | jq -r '.ETag')
取得したの設定内容から、認証を使う新しい設定内容を作成します。
NEW_CONFIG=$(echo $DIST_DATA | jq -c --arg arn "$FN_ARN" '
.DistributionConfig |
.DefaultCacheBehavior.FunctionAssociations = {
"Quantity": 1,
"Items": [
{
"FunctionARN": $arn,
"EventType": "viewer-request"
}
]
}
')
新しい設定を反映します。
aws cloudfront update-distribution \
--id $DIST_ID \
--if-match $DIST_ETAG \
--distribution-config "$NEW_CONFIG"
6.設定確認
CloudFront Distributionのビヘイビアを確認すると、関数が関連付けられています。

7.動作確認
DistributionのURLにアクセスすると、想定通り認証を求められます。

まとめ
CloudFrontで、簡単なコードで最低限の認証を実施することができました。
認証情報をコードに埋め込んでいるため望ましい構成ではないですが、最低限の認証としては機能するかなと思います。
