Web アプリケーションで Basic 認証時の HTTP パケットを覗いてみる

## はじめに
商用で利用される Web アプリケーションで、認証処理を行っていないものは少数だと思います。
また、認証方式や認証に関連する技術には様々なものがあり、それらを解説した書籍やサイトはたくさんあります。
ただ、認証時にクライアントとサーバーでやり取りされる HTTP パケットに着目したものはそれほど多くないように思いましたので、メモしておきたいと思います。

## 環境
・クライアント: Windows 10 (Internet Explorer 11))
・サーバー: Windows 10 (IIS 10.0)
今回は、クライアント・サーバーは同じマシンです。

## 準備
・IIS をインストールする。
今回はクライアント OS ですので、コントロール パネルの [プログラム] - [Windows の機能の有効化または無効化] から、[インターネット インフォメーション サービス] を有効にすることでインストールします。
具体的なインストール手順は、以下を<a href="http://pc-karuma.net/windows-10-turn-windows-features-on-or-off/" target="_blank">こちら</a>をご参照ください。  

・IIS に Web アプリケーションをデプロイする。
今回は<a href="https://msdn.microsoft.com/ja-jp/library/system.web.httpcontext.user.aspx" target="_blank">認証されたユーザーの情報</a>を表示するだけの ASP.NET アプリケーションを「AuthTest」という名前で作成しましたが、Web アプリケーションの中身は何でも構いません。

・HTTP キャプチャツールをインストールする
ブラウザーでもキャプチャが可能ですが、今回は Fiddler を利用します。
Fiddler は、HTTP に特化したパケットキャプチャツールです。
<a href="https://www.telerik.com/download/fiddler" target="_blank">こちら</a>からインストーラがダウンロードできます。
ダウンロード目的の選択とメールアドレスの入力が必要ですが、特にメールが届くといったことはありません。

## Fiddler でキャプチャしてみる
Fiddler を起動すると、自動的に HTTP (S) パケットのキャプチャが開始されます。その状態で、ブラウザ等で HTTP (S) でホストされているサイトにアクセスすると、パケットがキャプチャされます。
今回は、IIS 上で Basic 認証を有効化してホストされている ASP.NET アプリケーションにアクセスしてみます。

[手順]
1. ブラウザを起動
2. http://localhost/AuthTest/ にアクセス
3. 表示された資格情報を求めるダイアログに ID/PASSWORD を入力

[結果]
![image](https://qiita-image-store.s3.amazonaws.com/0/132638/bc2fac03-c770-f646-afd9-3f04d5fb196b.png)
(便宜上、フィルターをかけて表示しています)

上図 ①、②、③ はそれぞれ以下を示します。
①: アクセス時にはられた HTTP セッションの一覧
②: ① で選択しているセッションの HTTP Request Header
③: ① で選択しているセッションの HTTP Response Header


もう少し詳しく見ていきます。
まず ①。
![image](https://qiita-image-store.s3.amazonaws.com/0/132638/0fd6624f-f153-3184-b007-9d1f12949b31.png)
HTTP のセッションは 2 つで、1 つ目の Result が 401、2 つ目の Result が 200 であることが分かります。
ここで言う Result は HTTP Request への Result として返される Status Code です。
401 は認証が必要なために Request が拒否されたこと、200 は Request が成功したことを示します。
その他の HTTP Status Code については、[こちら](https://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89)をご参照ください。


次に ②。
① で 401 を返した方の HTTP Request Header です。
![image](https://qiita-image-store.s3.amazonaws.com/0/132638/c487638f-3a2e-f21a-a4dd-992d87604b18.png)
使用された HTTP メソッド (GET)、アクセス先 (/AuthTest/)、クライアントの情報 (User-Agent) などが含まれています。

最後に ③。
↑ の HTTP Request に対する Response Header ですね。
![image](https://qiita-image-store.s3.amazonaws.com/0/132638/20e584ae-599b-db40-f798-c9f04cf227ba.png)
認証に関して言うと、以下のような情報が含まれています。
・結果は 401 Unauthorized
・必要な認証方式は Basic で、対象領域は localhost (WWW-Authenticate: Basic realm="localhost")
その他、IIS 10.0 でホストされている ASP.NET アプリケーションであることも分かりますね (Server: Microsoft-IIS/10.0、X-Powered-By: ASP.NET)。

続いて、200 を返した方を見ていきます。
① は割愛して、まず ②。
![image](https://qiita-image-store.s3.amazonaws.com/0/132638/9c28b555-09a6-2e0c-c878-498e7c5becfe.png)
401 が返った方との違いは、Authorization ヘッダーが含まれていることです (Authorization: Basic dGVzdDE6cEBzc3cwcmQ=)。
Authorization は、認証に用いる資格情報を送信する際に使用されるヘッダーです。
ここでは、Basic 認証に対する資格情報として、dGVzdDE6cEBzc3cwcmQ= を送信しています。
なお、dGVzdDE6cEBzc3cwcmQ= を Base64 でデコードすると、簡単に test1:p@ssw0rd (ユーザーの ID:PASSWORD) が得られます。
Basic 認証が暗号化としては何の意味も持たないと言われる所以ですね。

最後に ③。
![image](https://qiita-image-store.s3.amazonaws.com/0/132638/b70af196-4daa-14ca-0f23-9a5a97590311.png)
結果は 200 (認証が通った) ことや、ASP.NET のバージョンも返されていますね (X-AspNet-Version: 4.0.30319)。

以上のことから流れを整理すると、
1. クライアントからサーバーへアクセス
2. 認証が必要なため、サーバーから 401 が返る
3. クライアントから資格情報を送信
4. 認証が通ればサーバーから 200 が返る (認証が通らなかった場合は、再び 401 が返ります)
となります。
他の認証方式でも、この流れはほぼ共通です。

##おわりに
最初はとっつきにくいところもあるパケットの解析ですが、一度ある程度のことが分かってしまえば、意外とシンプルで興味深いものです。

今回は Basic 認証を例にしましたが、認証時に通常どのような HTTP パケットがやり取りされるかを知っておくと、例えば、構成は正しいはずなのに認証が通らない場合や、Kerberos 認証を使いたいのに NTLM 認証に fallback されてしまう、といった現象のトラブルシューティングに役立ちます。

また、認証に限らず、Web アプリケーションからの応答速度が遅い場合に、クライアント - サーバー間の各径路のキャプチャを確認することで、どこで遅延が発生しているか切り分ける、といった使い方もできます。


以上、少しでもお役に立てば幸いです！