CloudFrontでベーシック認証

佐野

佐野 2015年7月22日

CloudFrontを使うとBasic認証が使えない?
と思いきや、じつは使う事ができます。

やり方は簡単で、CloudFrontの
「CloudFront Distributions」から項目を選択し、
「Behaiviors」タブの中からさらに項目を選択、
Behaiviors編集画面から、「Forward Headers」を「Whitelist」に変更します。
すると、以下の項目が表示されるので、
「Authorization」を右の枠に移動させます。

2015-07-21 18.19.44

設定は、これだけです。
これで、CloudFront越しでもベーシック認証が使用できます。
後は新しいコンテンツが、エッジロケーションへ反映されるのを待つだけ・・・
または、「Distributions」画面で、「Disable」→「Enable」を行い、強引に即時反映させます。

ベーシック認証には、「.htaccess」「.htpasswd」という、
外部から取得できないドットファイルを使用します。
ゆえに、これらのファイルはCloudFrontでも取得できないはずなのに、
なぜベーシック認証が成立するのかという点から、疑問を感じる人も多いことでしょう。

原理としましては、以下の通りです。

HTTPでコンテンツにアクセスする際、HTMLとして表示できるコード以外にも、
様々な情報が含まれた「ヘッダ」という情報が入っています。
この「ヘッダ」は、HTMLの「<head>」タグに囲まれた部分ではなく、
通常では確認する事のない部分に入っています。

それらの情報は、以下サイトが詳しく説明しています。
HTTPヘッダ一覧

今回のCloudFrontの設定では、ベーシック認証の情報が入っている
「Authorization」ヘッダの使用を許可するという設定です。

そこで、どのような方法でベーシック認証が実現されているのか、
オリジンサーバーのアクセスログを巡りながら調査してみました。

ここでは仮に「test」ディレクトリに対して、
「user」というユーザーで、ベーシック認証をかけた場合です。

204.246.186.49 - - [21/Jul/2015:18:11:34 +0900] "GET /test/index.html HTTP/1.0" 404 824 "-" "Amazon CloudFront"
204.246.186.49 - user [21/Jul/2015:18:11:41 +0900] "GET /test/index.html HTTP/1.0" 200 409 "-" "Amazon CloudFront"
204.246.186.49 - user [21/Jul/2015:18:11:57 +0900] "GET /test/test2/index.html HTTP/1.0" 200 361 "-" "Amazon CloudFront"

上から順に、

  • ユーザー・パスワードを求められたとき
  • ユーザー・パスワードの認証に成功したとき
  • さらに奥のページへアクセスしたとき

のログとなります。

最初、ベーシック認証でユーザーとパスワードを問われた際、
404レスポンス(コンテンツがない)で終わっていますが、
ベーシック認証でログインが成功した際、さらにその配下のディレクトリにアクセスした際に、
アクセスログが残っています。
「user」という名前のユーザー名で認証を行い、200レスポンス(コンテンツが存在した)も返しています。
ここまでは、CloudFrontを使用しない場合でも同じはずです。

しかし、この直後にchromeのシークレットウィンドウ(もしくは別ブラウザ)で
同じユーザーでベーシック認証を突破しても、ログが残る事はありませんでした。
おそらく、CloudFrontのエッジロケーションに保存されたコンテンツを見ているためでしょう。
この事から推測するに、CloudFront側では、認証に成功したユーザー名とパスワードを保存、
さらにユーザーごとのアクセス時のコンテンツが保存されていると考えられます。

ただ、ベーシック認証を使用すると、
認証するユーザーごとに、キャッシュをオリジンサーバーから取得する事になるので、
その分のオリジンサーバーへの負荷はかかる事になります。