« 02月23日の行動 | メイン | 本日の体操 »
2007年02月23日
[技術] CatalystとApacheモジュールのmod_auth_tkt
【技術メモ】
mod_auth_tkt : Apacheによる静的ファイルの配信時に閲覧許可チケットを与えられている場合のみに閲覧を許可するモジュール
ログイン認証した人だけが閲覧できるウェブサイトで、基本的には動的にデータベースからコンテンツを生成するのだが、画像ファイルなどの一部は静的に配信する場合、静的ファイルを配信するhttpサーバ(Apache)にも認証機能を付けないと、静的ファイルへのURLを直接指定された場合にログインしていない人でも閲覧できてしまう。
昔のmixiがそういう状態だったらしい(http://d.hatena.ne.jp/hasegawayosuke/20061017/p1)
確認していないが今は修正されたようだ(http://www.itmedia.co.jp/news/articles/0611/09/news078.html)
これは、メインコンテンツを配信するサーバA(main.example.jp)と画像などの静的ファイルを配信するサーバB(image.example.jp)を分けた場合に、ログイン認証はサーバAで行うなら、サーバAでの認証結果を何らかの方法でサーバBに伝えなければならない。そうしない場合、サーバBは認証無しで閲覧を許可するか(誰でも閲覧できる状態)、サーバBにアクセスがあった場合に再度ログイン認証する必要がある。
そこで、サーバAでの認証結果をサーバBに伝える仕組みを実現できるのが、Apacheのmod_auth_tktだ。正確には、サーバAで、サーバBへの閲覧チケットを発行し、ウェブブラウザにクッキーとして送り込む。そして、そのブラウザがサーバBのファイルにアクセスしたときにサーバBのmod_auth_tktがブラウザのクッキーチケットを確認し、閲覧を許可する。
で、このmod_auth_tktを使ってみようとしたのだが、検索しても、日本語どころか、英語でも設定例が見つからない。開発元のサイト(http://www.openfusion.com.au/labs/mod_auth_tkt/)とソースコードに付いているサンプルプログラムだけが頼りという状態だったので、動くようになるまで試行錯誤した。そこで、忘れた時のための備忘録として、設定例を残しておく。
■状況
サーバA(main.example.jp)でログイン認証を行い、メインコンテンツはサーバAが配信する。しかし、画像だけは、サーバB(image.example.jp)は配信することにする。
■サーバAのログイン認証時にサーバBへの閲覧チケットを発行する
(Perlで、フレームワークにCatalystを利用している場合)
CPANより、Apache::AuthTktを取得する
my $secret = "MD5のチェックSUMで、サーバBのApacheの設定ファイルに記述されているのと同じもの";
my $expires = '+60s';
my $domain = '.example.jp';
my $at = Apache::AuthTkt->new( secret => $secret );
my $ticket = $at->ticket( uid => $userid, ip_addr => undef );
$c->res->cookies->{auth_tkt} = {
value => $ticket,
expires => $expires,
domain => $domain,
path => '/',
secure => 0};
$at->ticket()のip_addrにundefを指定しているのは、サーバBの設定で、 TKTAuthIgnoreIP onとした場合はundef を明示的に指定しないと、Apache::AuthTkt->ticket()がデフォルトでクライアントのIPアドレス以外のアクセスを認めないチケットを生成する。今回の場合はなぜか、undef しておかないと、期待通りの動作にならなかった。
Cookie名は、サーバBのApacheの設定で、 TKTAuthCookieNameに指定したのと同じにする。今回の場合は、 auth_tkt。
これは、CatalystでのCookie生成方法であるが、とにかく Catalystでなくても、Cookieのチケットを生成して、ブラウザに送り込めばよい。
■サーバBのApacheの設定
例えば、image.example.jp/images/に画像が格納されており、そこにアクセスするにはチケットが必要にするには、Apacheの設定を以下のようにする。
# Protected directory example Alias /images /var/www/images <Directory /var/www/images> AuthType Basic require valid-user TKTAuthCookieName auth_tkt TKTAuthIgnoreIP on TKTAuthTimeoutMin 60 </Directory>
とりあえず、これで、サーバAにログインしてない状態で、image.example.jp/imagesにアクセスすれば拒否され、ログインしていれば、閲覧できるようになる。
投稿者 nekobara : 2007年02月23日 22:10
コメント
こうゆう仕組みで対処しているのですね。
といっても内容はちんぷんかんぷんですが
ニュアンスだけでも参考になります。
Catalyst使いまくってますね♪
またN@velでデモ開催してくださいねぇ
投稿者 後藤 : 2007年02月24日 16:44
後藤さん、どうもです。
アクセスが増えた時のスケールアウトを考えると、
DBからメインコンテンツと静的ファイルの配信サーバは
分けて行くことになるので、この実装は結構重要です。
Catalystなどのフレームワークなしでの開発はもはや考え
られません。
投稿者 nekobara : 2007年02月26日 09:28