CloudFrontにBasic認証をかけたーーい!
ということで、
S3がオリジンのCloudFrontで公開しているWEBアプリにBasic認証をかけます。
実装方針
上記を見ると、CloudFront Functionsで簡単に実装できるみたいです。
CloudFront Functions とは?
まずは、デフォルトディレクトリインデックスの実装に必要なCloudFront Functionsについて。
特定のイベントタイプに対して、事前に定義しているJavaScriptの関数を実行できる機能のこと。
イベントタイプには2種類あり、
- ビューワーリクエスト:ビューワーからリクエストを受信したとき
- ビューワーレスポンス:ビューワーにレスポンスを返す前
リクエスト(レスポンス)ヘッダーの操作やリダイレクト処理などを実現できます。
公式ドキュメントは↓です。目を通してみるといいと思います
CloudFront Functions の料金
公式サイトより、
100 万件の呼び出しあたり 0.10 USD です (1 回の呼び出しごとに 0.0000001 USD)。
また、無料枠として
各月 2,000,000 件の CloudFront Function 呼び出し
が設けられています。
実装
事前準備
Basic認証では、
ブラウザから、ユーザ名とパスワードをコロン “:” でつなぎ Base64でエンコードして送信します。
Cloudfront Fuctions で送信された文字列(認証情報)が正しいか判断します。
そのため、Base64でエンコードされた文字列を用意しておき、JavaScript内で判定する際に使用します。
今回は、
ユーザ名:hisui
パスワード:hisuipw
具体的には下記コマンドでエンコードされた文字列を用意します
1 2 |
$ echo -n "hisui:hisuipw" | base64 aGlzdWk6aGlzdWlwdw== |
この文字列を次のCloudfront Fuctions で使用します
CloudFront Functions
CloudFront Functions で実行する関数はこちらのコードをそのまま使います
jsファイルを作成し、tfファイルから参照するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function handler(event) { var request = event.request; var headers = request.headers; // echo -n user:pass | base64 var authString = "Basic aGlzdWk6aGlzdWlwdw=="; if ( typeof headers.authorization === "undefined" || headers.authorization.value !== authString ) { return { statusCode: 401, statusDescription: "Unauthorized", headers: { "www-authenticate": { value: "Basic" } } }; } return request; } |
authString にユーザー名, パスワードをbase64でエンコードしたものを指定し、
認証情報を送信していないもしくは、誤った認証情報を送信しているときに401を返します。
ヘッダーの”www-authenticate” に”Basic”を指定し、Basic認証を使うとブラウザに伝えます
つまり、
認証情報を送信していない初めのリクエストに対して401とBasic認証を使うことを伝えます。
2回目以降は送られてきた認証情報を判定し、
・あっている場合は、認証を通し、
・空欄もしくは間違っている場合は再度Basic認証でユーザー名とパスワードをききます
詳しく知りたい方は下記2つをご覧ください
Terraform
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
resource "aws_cloudfront_distribution" "main" { ... default_cache_behavior { ... # CloudFront Functionsの紐づけ function_association { event_type = "viewer-request" function_arn = aws_cloudfront_function.main.arn } } ... } ... # CloudFront Functions resource "aws_cloudfront_function" "main" { name = "function" runtime = "cloudfront-js-1.0" comment = "Basic認証" publish = true code = file("./CloudFront_Functions/function.js") } |
aws_cloudfront_distribution > default_cache_behavior ブロック内で
CloudFront Functionsを紐づけていきます
プロパティ | 説明 |
event_type | どのイベントタイプで実行するか viewer-request に対して関数を実行します |
function_arn | 後ほど定義するCloudFront Functions のARNを指定します |
aws_cloudfront_function にて、CloudFront Functions を定義します。
プロパティ | 説明 |
name ※ | CloudFront Functions の名前 |
runtime ※ | ランタイム。2023/07現在、cloudfront-js-1.0 のみ指定可能 |
comment | コメント。 |
publish | 関数をデプロイするかどうか。デフォルトはtrue。 テストなどをしたい方はデプロイしない(false) ことも可能。 |
code ※ | 関数のソースコード。先ほど作成したjsファイルを相対パスで指定。 |
※ は必須項目
plan , apply
1 2 |
$ terraform plan $ terraform apply -auto-approve |
ダウンタイムはなかったと思います。。。
動作確認
CloudFront のドメインにアクセスして、下記のようにBasic認証が表示されます。
ここで、
ユーザ名:hisui
パスワード:hisuipw
を入力し、認証できればOKです!
参考記事
コメント