Basic認証(HTTP認証)とフォームによる認証を比較しつつ、ユーザ認証についてまとめてみた。
認証の仕組みについて、概念的なところのふわっとした理解の足しにする目的で書いている。
Webは基本的にオープンなネットワークである。接続さえしてしまえば世界中の膨大な数のWebサービスにアクセスできる。逆に自らサービスをWeb上で公開したとしたら、全世界のあらゆる端末からリクエストを受ける可能性がある。誰とでも通信できるだけでなく、通信内容は誰もがアクセスできるネットワークの上を行き来して行われる。このようなWeb上での通信は
- なりすまし
- 改ざん
- 事後否認(自分が行った通信を、他人のなりすましや改ざんのせいだ、と言い張る行為)
- 盗聴
といったセキュリティ上の脅威に常にさらされている。このためWebサービスを作る上で、「通信相手が誰であるかを証明する」=「ユーザ認証」の仕組みが必要になってくる。実用的なユーザ認証に対する要件は、
要件1. 手続きが簡単であり使いやすい、あるいはサービス側で実装しやすいこと
要件2. セキュリティが強固であること
という2つが基本だ。難しいのはこの2つの要件はトレードオフの関係にあることだと思う。
Basic認証とフォームによる認証
よく利用される認証方式として、Basic認証とフォームによる認証の2つがある。それぞれ、ユーザがユーザIDとパスワードを入力してサーバ側でそれを検証する、という基本原理は同じだが、内部の仕組みと使いどころが違う。
Basic認証は一般ユーザ向けのサービスで利用されることはないが、一般公開されておらず利用者が限定されている内部的なWebサービスでは利用されることも多い。一方でフォームによる認証は現状のWebサービスにおける、ユーザ認証の主流となっている。
2つの認証方式を比較する上で、認証の手続きを以下の3ステップに分けて説明してみる。
- 事前準備は何か?
- 認証成立の手続きはどのようなものか?
- 認証成立後、認証情報をどのように管理するか?
Basic認証
手順は以下のようになる。
- サーバ側でユーザID・パスワードを設定してこれをユーザに(メールなど)で配布する.
- ユーザは、サーバにアクセスしたとき、ブラウザのBasic認証用の入力フォームを利用して、ユーザ名とパスワードを入力する。サーバ側では、HTTPサーバが送られてきたリクエストのヘッダを見て、ユーザを認証する。
- 一度ログインが確立した後はブラウザが前回入力されたユーザID・パスワードを覚えていて、自動でHTTPのAuthorizationヘッダにユーザIDとパスワードを埋め込んで送信する. 2.と同様に、HTTPサーバがリクエストのAuthorizationヘッダのユーザ名とパスワードを検証してユーザを認証する。
Basic認証はHTTP認証としてRFC2617で規定されている認証方式の一つである。
HTTP認証には、Digest認証という方式もあるが通信時にユーザID・パスワードをハッシュ化する点がBasic認証とは異なるだけなので、ここでは説明を割愛する。
上記のRFCに注意書きされているように、Basic認証は最も簡単で便利だが、それ単体では安全な認証方式ではない.
ユーザID・パスワードが通信経路上にそのまま送られるため、パスワード漏洩のリスクが大きいためだ。
"HTTP/1.0", includes the specification for a Basic Access
Authentication scheme. This scheme is not considered to be a secure
method of user authentication (unless used in conjunction with some
external secure system such as SSL [5]), as the user name and
password are passed over the network as cleartext.
さらに、後述のフォーム認証と比較して、ログアウトできない、ホストをまたいだシングルサインオンが難しい、といった機能的に劣る点がある(https://www.rcis.aist.go.jp/special/MutualAuth/faq/detail-ja.html#formauth). 一方で、Basic認証はHTTPサーバの設定だけで簡単に実現できるため、内部システムの認証方式としては使い勝手が良い.
フォームによる認証
ここでは、「フォーム入力によるユーザID・パスワードの送信とクッキーを用いたセッション管理」によるユーザ認証を、「フォームによる認証」と呼んでいる。現在のWebサービスではフォームによるユーザ認証を行うのが普通だ。
具体的な手順は、
- ユーザ登録ページにて、ユーザが自分で指定したキーとシークレットをサーバ側に登録する。
- ユーザは、ログインページにて、ユーザID・パスワードを入力し送信する。サーバ側ではこれを検証し、登録されているユーザID・パスワードと一致すれば認証を確立する。このとき、認証情報を保存する目的で、セッションIDを発行しレスポンスクッキーにセッションIDを付与する。サーバ側でもにもユーザIDとセッションIDをひもづけて保管しておく。
- 次回のユーザリクエスト時には、ブラウザがサーバからもらったクッキーをリクエストに付与して送信する。サーバ側は、リクエストクッキー内のセッションIDを、サーバ側で記録しておいたセッションIDと比較検証することで、ユーザのログイン状態を判定する。
上記の認証処理はBasic認証(HTTP認証)と異なり、Webアプリ・サーバ側で実装される。前述のとおり、フォームによる認証のサービス・システム設計・実装のポイントはいろいろある。例えば、どのタイミングでログインを要求するか(非ログインでどこまでサービスを利用できるか)、セキュリティホールを作らないログイン・ログアウトの実装、ホスト間でのシングルサインオン、といった点をサービスに合わせてに設計・実装する必要がある。