CloudFrontを通過する特定のパスのみにBasic認証を設定してみた
こんにちは、AWS事業本部の荒平(@0Air)です。
特定のパスのみにBasic認証を設定したいという相談をいただきました。
以下の記事をベースに設定できますが、コンソール画面の表示が改修の度に変わるため、主にAWS CLIを利用して最初から確認してみます。
CloudFront Functions(関数)の作成
ディストリビューションを作成する前に、CloudFront Functionsの関数を作成します。
CloudShellにて、以下のコマンドを使用します。ID/Passwordは適宜読み替えてください。
echo -n "classmethod:P@ssw0rd" | base64
出力された文字列を利用します(ここでは、Y2xhc3NtZXRob2Q6UEBzc3cwcmQ=
)
以下のコードを、任意のファイル名で保存します。(ここでは、basic-auth.js
)
6行目のBasic認証の文字列は、各自で書き換えが必要です。
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行目)は各環境において書き替えてください。
{ "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)がお送りしました!