こんにちは、AWS事業本部の荒平(@0Air)です。
特定のパスのみにBasic認証を設定したいという相談をいただきました。
以下の記事をベースに設定できますが、コンソール画面の表示が改修の度に変わるため、主にAWS CLIを利用して最初から確認してみます。
CloudFront Functions(関数)の作成
ディストリビューションを作成する前に、CloudFront Functionsの関数を作成します。
CloudShellにて、以下のコマンドを使用します。ID/Passwordは適宜読み替えてください。
echo -n "classmethod:P@ssw0rd" | base64
出力された文字列を利用します(ここでは、Y2xhc3NtZXRob2Q6UEBzc3cwcmQ=
)
以下のコードを、任意のファイル名で保存します。(ここでは、basic-auth.js
)
6行目のBasic認証の文字列は、各自で書き換えが必要です。
basic-auth.js
function handler(event) {
var request = event.request;
var headers = request.headers;
// echo -n user:pass | base64
var authString = "Basic Y2xhc3NtZXRob2Q6UEBzc3cwcmQ=";
if (
typeof headers.authorization === "undefined" ||
headers.authorization.value !== authString
) {
return {
statusCode: 401,
statusDescription: "Unauthorized",
headers: {
"www-authenticate": { value: "Basic" }
}
};
}
return request;
}
CloudShell上で以下のコマンドを実行して、CloudFront 関数を作成、パブリッシュします。
1行目の作成を走らせた際にETag
が生成されるので、これを2行目で使います。
aws cloudfront create-function --name "basic-auth" --function-config '{"Comment":"My function","Runtime":"cloudfront-js-2.0"}' --function-code fileb://basic-auth.js
aws cloudfront publish-function --name "basic-auth" --if-match ETVPDKIKX0DER(Etag名)
それぞれ、以下のような応答が返っていれば、上手く作成できています。
(返らない場合は、CloudShellを操作するIAMユーザーの権限を見直してください)
[cloudshell-user@ip-10-134-7-94 ~]$ aws cloudfront create-function --name "basic-auth" --function-config '{"Comment":"My function","Runtime":"cloudfront-js-2.0"}' --function-code fileb://basic-auth.js
{
"Location": "https://cloudfront.amazonaws.com/2020-05-31/function/arn:aws:cloudfront::000000000000:function/basic-auth",
"ETag": "ETVPDKIKX0DER",
"FunctionSummary": {
"Name": "basic-auth",
"Status": "UNPUBLISHED",
"FunctionConfig": {
"Comment": "My function",
"Runtime": "cloudfront-js-2.0"
},
"FunctionMetadata": {
"FunctionARN": "arn:aws:cloudfront::0000000000000:function/basic-auth",
"Stage": "DEVELOPMENT",
"CreatedTime": "2024-02-15T14:47:34.770000+00:00",
"LastModifiedTime": "2024-02-15T14:47:34.770000+00:00"
}
}
}
[cloudshell-user@ip-10-134-7-94 ~]$ aws cloudfront publish-function --name "basic-auth" --if-match ETVPDKIKX0DER
{
"FunctionSummary": {
"Name": "basic-auth",
"Status": "UNASSOCIATED",
"FunctionConfig": {
"Comment": "My function",
"Runtime": "cloudfront-js-2.0"
},
"FunctionMetadata": {
"FunctionARN": "arn:aws:cloudfront::0000000000000:function/basic-auth",
"Stage": "LIVE",
"CreatedTime": "2024-02-15T14:52:27.691000+00:00",
"LastModifiedTime": "2024-02-15T14:52:27.691000+00:00"
}
}
}
コンソール画面にて、以下のような状態になっていれば問題ありません。
CloudFront Distributionの設定
CloudFront Distributionを設定します。
以下ディストリビューションの設定ファイルを作成し、任意の名前で保存します。(ここでは、dist-config.json
)
デフォルトパスへのアクセスは何もせず、/auth
パスのみ先程の関数が呼び出されるようにします。
オリジン名(12行目)、関数のARN(59行目)は各環境において書き替えてください。
dist-config.json
{
"CallerReference": "unique-caller-reference",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "S3",
"DomainName": "arap.s3-website-ap-northeast-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "http-only",
"OriginSslProtocols": {
"Quantity": 3,
"Items": ["TLSv1", "TLSv1.1", "TLSv1.2"]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
}
}
]
},
"DefaultCacheBehavior": {
"TargetOriginId": "S3",
"ViewerProtocolPolicy": "allow-all",
"ForwardedValues": {
"QueryString": false,
"Cookies": {
"Forward": "none"
}
},
"MinTTL": 0,
"DefaultTTL": 86400,
"MaxTTL": 31536000,
"FunctionAssociations": {
"Quantity": 0
}
},
"CacheBehaviors": {
"Quantity": 1,
"Items": [
{
"PathPattern": "/auth/*",
"TargetOriginId": "S3",
"ViewerProtocolPolicy": "redirect-to-https",
"FunctionAssociations": {
"Quantity": 1,
"Items": [
{
"EventType": "viewer-request",
"FunctionARN": "arn:aws:cloudfront::000000000000:function/basic-auth"
}
]
},
"ForwardedValues": {
"QueryString": true,
"Cookies": {
"Forward": "all"
}
},
"MinTTL": 0,
"DefaultTTL": 0,
"MaxTTL": 0
}
]
},
"Comment": "CloudFront Function for /auth path",
"Enabled": true
}
保存したら、CloudShellから、CloudFront Functionを紐付けた状態のディストリビューションを作成します。
aws cloudfront create-distribution --distribution-config file://dist-config.json
動作確認
オリジンのS3にはindex.html
をひとつ置いてあります。(構成の参考は以下を御覧ください)
デフォルトパス(/index.html
)にアクセスした場合は、ページ内容が表示されます。
制限したいパス(/auth/*
)にアクセスした際には、Basic認証が出現することを確認できました。
CloudFront Functionで指定したID/パスワードを入力することで、認証したのちにファイルを読み込むことができます。
おわりに
「一時的にWebサイトを公開したいけど、完全無防備はちょっと・・・」というニーズがある場合に使えそうです。
CloudFront Functionsを用いるとサクッとBasic認証をかけることができるため、お困りの方は試す価値がありそうです。
このエントリが誰かの助けになれば幸いです。
それでは、AWS事業本部 コンサルティング部の荒平(@0Air)がお送りしました!