2014年7月27日

CloudFront で Basic 認証使う

CloudFront でみんな大好き Basic 認証を使ってみます。CloudFront はデフォルトでは Authorization ヘッダをオリジンサーバへ転送しないため、Basic 認証を使えません。

こちらのアップデートで転送するヘッダを選択できるようになりました。

【AWS発表】CloudFrontでカスタムコンテンツの配信が可能に
http://aws.typepad.com/aws_japan/2014/07/enhanced-cloudfront-customization.html


実際に試してみます。

Basic 認証の設定

Basic 認証は以下を参考に有効化します。

@IT Apacheでユーザー認証を行うには(Basic認証編)
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/698apachebasic.html


パスワードを設定します。
# htpasswd -c /etc/httpd/.htpasswd hoge
New password:
Re-type new password:
Adding password for user hoge

httpd.conf の Directory の中に Basic 認証の設定を追加します。ドキュメントルートに設定するため、<Directory "/var/www/html"> の中に追加しています。
AuthType Basic
   AuthName "Secret Zone"
   AuthUserFile /etc/httpd/.htpasswd
   Require user hoge

httpd を再起動。(止まってたので停止には失敗してしましました)
# service httpd restart
Stopping httpd:                                            [FAILED]
Starting httpd:                                            [  OK  ]

テスト用のファイルを作成します。test と出力されれば成功です。
# echo test > /var/www/html/test.txt
# cat /var/www/html/test.txt
test

まずは localhost でテストします。Authorization ヘッダで Basic 認証のユーザ:パスワードを渡すと成功します。
# curl localhost/test.txt
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Authorization Required</title>
</head><body>
<h1>Authorization Required</h1>
<p>This server could not verify that you
are authorized to access the document
requested.  Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
<hr>
<address>Apache/2.2.27 (Amazon) Server at localhost Port 80</address>
</body></html>
# curl localhost/test.txt  -H "Authorization:Basic aG9nZTpmdWdh"
test

httpd のアクセスログにもユーザが出力されています。
127.0.0.1 - - [27/Jul/2014:11:47:29 +0000] "GET /test.txt HTTP/1.1" 401 476 "-" "curl/7.36.0"
127.0.0.1 - hoge [27/Jul/2014:11:47:31 +0000] "GET /test.txt HTTP/1.1" 200 5 "-" "curl/7.36.0"


CloudFront に設定

CloudFront で Authorization ヘッダを Whitelist に追加します。一覧から Authorization を選択し、Add で右側のリストに移動します。


CloudFront 側の設定が終わったので、今度は CloudFront 経由でテストします。
# curl abcdefghijklmn.cloudfront.net/test.txt
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Authorization Required</title>
</head><body>
<h1>Authorization Required</h1>
<p>This server could not verify that you
are authorized to access the document
requested.  Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
<hr>
<address>Apache/2.2.27 (Amazon) Server at ec2-255-255-255-255.ap-northeast-1.compute.amazonaws.com Port 80</address>
</body></html>
# curl abcdefghijklmn.cloudfront.net/test.txt  -H "Authorization:Basic aG9nZTpmdWdh"
test
うまくいきました。

ログも CloudFront 経由となっています。
54.239.196.112 - - [27/Jul/2014:11:59:46 +0000] "GET /test.txt HTTP/1.1" 401 521 "-" "Amazon CloudFront"
54.239.196.112 - hoge [27/Jul/2014:11:59:59 +0000] "GET /test.txt HTTP/1.1" 200 5 "-" "Amazon CloudFront"


Basic 認証を CloudFront でも使えるようになりましたが、前述のブログにあるように「ヘッダーの値がキャッシュのキーの一部になります」ので、結果的にユーザ毎にキャッシュされるため、ユーザが増えたらキャッシュ効率が下がってしまいます。このあたりは動的コンテンツと同じですね。