このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
今日は、WWW 認証の動作を追いかけてみる。
前回同様、Web サーバとしては Apache を使う。
Apache は、組み込みで WWW 認証をサポートしており、
適切な設定を行うだけで認証を行うことができる。
以下は、Apache 固有の話になるが、
テストのために必要なので書いておこう。
まず、特定のディレクトリに対してアクセス制限をかける。
これは、httpd.conf または .htaccess で設定をする。
今回は、.htaccess を使うことにしよう。
========== .htaccess ==========
Require valid-user
AuthType Basic
AuthName "Restricted Zone"
AuthUserFile /path/to/.htpasswd
========== end of .htaccess ==========
Require は、ここではアクセス制限を行う事を示す。
valid-user を指定すると、認証済みユーザのみが、
このディレクトリ配下にアクセス可能となる。
AuthType は、認証の方法を指定するものであり、
Basic は、最も単純な「基本認証」と呼ばれる仕組みだ。
基本認証は平文でパスワードを受け渡すことを示す。
先に触れておくが、今回は「HTTP の理解を目的」として
基本認証を使った例を示しているが、
実運用では、SSL と組み合わせない限り使わないこと。
(SSL を使うにしても 基本認証は推奨されない)
というのも、TCP のパケットは簡単に盗聴できるので、
セキュリティを考慮していない実装のまま運用している、
FTP や POP3 と同等の危険性があるのだ。
では、本題に戻る。
AuthName は、アクセス制限下の領域の説明文だ。
これは、Web ブラウザが画面の表示に利用する。
AuthUserFile は、ユーザとパスワードが記録されている
ファイル(パスワードファイル)へのパスである。
次に、パスワードファイルを作成する。
このファイルは、htpasswd コマンドで作成可能だ。
ここでは、ユーザ「user」パスワード「password」とする。
$ htpasswd -c /path/to/.htpasswd user
New password:[password と入力]
Re-type new password:[password と入力]
Adding password for user user
こうすればパスワードファイルが生成される。
ハッシュ化に利用するアルゴリズムによっても異なるが、
パスワードファイルは、大体以下のような内容となる。
user:UAbDU3A0F1XzE
後は、これらのファイルを Apache で公開する場所に置く。
/(適当)/mixi/restricted/
.htaccess
.index.html(OK と書かれたダミーのファイル)
/path/to/
.htpasswd(パスワードファイル)
ここでは例として、以下の URL に配置してみた。
http://loafer.jp/mixi/restricted/
さて、では Fiddler を起動し、
Web ブラウザでこの URL にアクセスしてみよう。
まず、ユーザ認証のダイアログボックスが画面に表示される。
写真に示したのは Internet Explorer の例だ。
「Restricted Zone」という文字が見える。
これは、Apache で設定した説明文であり、
この時点で、HTTP による通信が一度行われている。
では、Fiddler でセッションを見てみよう。
Web ブラウザのリクエストは一般的なものだが、
Web サーバのレスポンスが少し異なる。
ではステータス行とヘッダ行を抜き出してみよう。
========== Response #1 ==========
HTTP/1.1 401 Authorization Required
Date: Mon, 04 Sep 2006 09:44:18 GMT
Server: Apache
WWW-Authenticate: Basic realm="Restricted Zone"
Connection: close
Content-Type: text/html; charset=iso-8859-1
========== end of Response #1 ==========
アクセス制限が掛かった Web ページへのリクエストの場合、
Web サーバは、ステータスコード 401 と共に、
WWW-Authenticate ヘッダを追加して返す。
このヘッダには、Web サーバがサポートする認証方法と、
アクセス制限の掛かった領域の説明文が含まれる。
401 ステータスを受け取った Web ブラウザは、
ページへのアクセスには認証が必要と判断し、
領域の説明文と共に、認証用の画面を表示する。
ここまでが、1 度の通信だ。
では、ここで間違ったパスワードを入れてみよう。
ユーザ「user」、パスワード「badpass」と入力してみる。
そうすると、Web ブラウザは認証情報を作成し、
それをヘッダに追加して再度リクエストを送る。
そうすると、再度ダイアログボックスが画面に表示された。
一見何も行われていないように見えるが、
ここでも HTTP による通信が行われている。
今度は Web ブラウザのリクエストの、
リクエスト行とヘッダ行を抜き出してみよう。
写真に示しているのはこの 2 回目の通信内容だ。
========== Request #2 ==========
GET /mixi/restricted/ HTTP/1.0
Accept: */*
Accept-Language: ja,en-us;q=0.7,en;q=0.3
X-ProcessAndThread: iexplore.exe [2244; 2256]
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 1.1.4322)
Host: loafer.jp
Proxy-Connection: Keep-Alive
Authorization: Basic dXNlcjpiYWRwYXNz
========== enf of Request #2 ==========
2 回目のリクエストは、ほぼ最初のリクエストと同じで、
Authorization ヘッダが追加されている点のみが異なる。
このヘッダには、Web ブラウザが選択した認証方法と、
ユーザ認証情報が含まれている。
上の例では、「dXNlcjpiYWRwYXNz」が認証情報だ。
これは、一見暗号化されているように見えるが、
Base64 と呼ばれるアルゴリズムで変換されているだけだ。
このアルゴリズムは、主にメールなどで広く利用されており、
簡単に元のデータに戻すことができる。
上記の認証情報を元に戻すと「user:badpass」となる。
前述した通り、基本認証では、
平文でパスワードが流れていることが分かる。
さて、間違った認証情報を送った場合、
Web サーバのレスポンスは、
認証情報を送らなかった場合と全く同じとなる。
この場合、Web ブラウザは認証が失敗したと判断し、
認証の再試行を行うために、再度入力を求めたわけだ。
では、正しい認証情報を入力してみよう。
今度は成功したので、「OK」と表示された。
Fiddler で通信を見てみると、
Web ブラウザのリクエストは上と同様であり、
やはり Authorization ヘッダが追加されている。
今回は認証が通ったので、Web サーバは
通常通り 200 のステータスでページを返却した。
WWW 認証は、以上の手順によって行われている。
ユーザ名やパスワード入力画面を出すのは、
Web ブラウザの役割なのである。
また、認証が 3 回失敗すると、失敗の画面になるが、
この画面は、401 ステータスと共に毎回
Web サーバが返している HTML である。
3 回で失敗するのは、慣習に沿った Web ブラウザの仕様で、
サーバ側には回数などの決まりは存在しない。
なお、一度認証が成功した後は、
Web ブラウザは、認証が成功したディレクトリ以下への
アクセスに Authorization ヘッダを自動的に追加する。
これは、アクセス制限下にある URL にアクセスする場合、
そのリクエスト全てに認証情報が必要となるため、
もし Authorization ヘッダがなければ、
Web サーバが 401 を返すことが予想されるからである。
この認証情報の自動送信を止めるためには、
一般的には Web ブラウザを終了させるしかない。
このため、基本認証を使う場合は、
パスワードが流出する危険性は更に大きくなるのだ。