HTTP はアクセス制御と認証の基本的な枠組みを提供しています。このページでは、HTTP の認証の枠組みを紹介し、サーバーで HTTP の "Basic" 認証を使用してアクセスを制限する方法を紹介します。
一般的な HTTP 認証の枠組み
RFC 7235 は、サーバーがクライアント要求を challenge し、クライアントが認証情報を提供するために使用できる HTTP 認証フレームワークを定義しています。
チャレンジとレスポンスの流れは以下のようになります。
- サーバーは少なくとも1回のチャレンジで、クライアントに
401
(Unauthorized) レスポンスステータスを返し、WWW-Authenticate
レスポンスヘッダーを含めて認証方法に関する情報を提供します。 - サーバーで自身を認証したいクライアントは
Authorization
リクエストヘッダフィールドに資格情報を含めることでそれを行うことができます。 - 通常、クライアントはユーザーにパスワードのプロンプトを表示し、正しい
Authorization
ヘッダーを含むリクエストを発行します。
この図に示したような "Basic" 認証の場合、やり取りは安全のために HTTPS (TLS) 接続を介して行われなければなりません。
プロキシ認証
プロキシ認証にも同じチャレンジとレスポンスのメカニズムを使用できます。リソース認証とプロキシ認証の両方が共存できるため、異なるヘッダーとステータスコードのセットが必要です。プロキシの場合、チャレンジのステータスコードは 407
(Proxy Authentication Required) で、 Proxy-Authenticate
レスポンスヘッダーはプロキシサーバーに資格情報を提供するために、 Proxy-Authorization
リクエストヘッダーが使用されます。
アクセスの不許可
特定のリソースにアクセスするのに十分ではないが有効な資格情報を (プロキシ) サーバーが受け取った場合、サーバーは 403
Forbidden
ステータスコードを返す必要があります。 401
Unauthorized
または 407
Proxy Authentication Required
とは異なり、このユーザーは認証できません。
オリジン間の画像の認証
ブラウザーによって最近修正された潜在的なセキュリティホールとして、サイト間での画像の認証があります。 Firefox 59 以降、異なるオリジンから現在の文書に読み込まれる画像リソースは、 HTTP 認証ダイアログを起動することができなくなり (バグ 1423146)、攻撃者が任意の画像をサードパーティ製のページに埋め込んでユーザーの認証情報を盗むことを防ぎます。
HTTP 認証の文字エンコーディング
ブラウザーはユーザー名とパスワードに utf-8
エンコーディングを使用します。
Firefox は ISO-8859-1
を使用していましたが、他のブラウザーとの互換性のために utf-8
に変更され、 バグ 1419658 で説明されているような潜在的な問題を回避します。
WWW-Authenticate および Proxy-Authenticate ヘッダー
WWW-Authenticate
および Proxy-Authenticate
レスポンスヘッダーは、リソースへのアクセスに使用する認証メソッドを定義します。どの認証方式を使用するかを指定するため、認証を希望するクライアントは資格情報の提供方法を知ることができます。これらのヘッダーの構文は次のとおりです。
これらのヘッダーの構文は以下の通りです。
WWW-Authenticate: <type> realm=<realm> Proxy-Authenticate: <type> realm=<realm>
ここで、 <type>
は認証スキームです ("Basic" は最も一般的なスキームであり、以下で紹介します)。 realm は保護された領域を説明するため、または保護の範囲を示すために使用されます。これは、「ステージングサイトへのアクセス」などのようなメッセージにすることができ、それによってユーザーが、どの領域にアクセスしようとしているかを知ることができます。
Authorization および Proxy-Authorization ヘッダー
Authorization
および Proxy-Authorization
リクエストヘッダーには、(プロキシ) サーバーがユーザーエージェントを認証する資格情報が入ります。ここでは、 <type>
が再び必要となり、その後に使用される認証方式によって符号化または暗号化された資格情報が続きます。
Authorization: <type> <credentials> Proxy-Authorization: <type> <credentials>
認証方式
一般的な HTTP 認証フレームワークは、いくつかの認証方式によって使用されます。スキームはセキュリティ強度とクライアント、またはサーバーソフトウェアでの可用性が異なる場合があります。
最も一般的な認証方式は "Basic" 認証方式であり、これについては以下で詳しく説明します。 IANA は認証スキームの一覧を管理していますが、 Amazon AWS などのホストサービスが提供する他のスキームもあります。一般的な認証方式には次のものがあります。
- Basic
- RFC 7617 を参照。 base64 でエンコードされた資格情報です。詳しくは後述します。
- Bearer
- RFC 6750 を参照。 OAuth 2.0 で保護されたリソースにアクセスするベアラトークンです。
- Digest
- RFC 7616 を参照。 Firefox では md5 ハッシュだけに対応しています。 SHA 暗号化の対応については バグ 472823 を参照。
- HOBA
- RFC 7486 3章 を参照、HTTP オリジン認証 (HTTP Origin-Bound Authentication)、電子署名ベース
- Mutual
- RFC 8120 を参照
- AWS4-HMAC-SHA256
- AWS docs を参照
Basic 認証方式
"Basic" HTTP 認証方式は RFC 7617 で定義されており、Base64 を使用してエンコードされたユーザー ID とパスワードのペアとしてクレデンシャルを送信します。
Basic 認証の安全性
ユーザー ID とパスワードはネットワークを介してクリアテキスト (base64 でエンコードされていますが、 base64 は可逆エンコードです) として渡されるため、 Basic 認証方式は安全ではありません。 Basic 認証と組み合わせて HTTPS/TLS を使用する必要があります。これらの追加のセキュリティ強化機能がない場合は、機密情報や重要な情報を保護するために Basic 認証を使用しないでください。
Apache と Basic 認証によるアクセス制限
Apache サーバー上のディレクトリをパスワードで保護するには、 .htaccess
ファイルと .htpasswd
ファイルが必要です。
.htaccess
ファイルは通常、次のようになります。
AuthType Basic AuthName "Access to the staging site" AuthUserFile /path/to/.htpasswd Require valid-user
.htaccess
ファイルは .htpasswd
ファイルを参照し、各行にはユーザー名とパスワードをコロン (":") で区切って記述します。実際のパスワードは暗号化されている (この場合は md5) ので表示できません。必要に応じて .htpasswd
ファイルの名前を変更することができますが、このファイルには誰にもアクセスできないように注意してください。(Apache は通常 .ht*
ファイルへのアクセスを禁止するように設定されています)。
aladdin:$apr1$ZjTqBB3f$IF9gdYAGlMrs2fuINjHsz. user2:$apr1$O04r.y2H$/vEkesPhVInBByJUkXitA/
nginx と Basic 認証によるアクセス制限
nginx の場合は、保護する場所とパスワードで保護された領域に名前を指定する auth_basic
ディレクティブを指定する必要があります。auth_basic_user_file
ディレクティブは上の Apache の例のように、暗号化されたユーザー資格情報を含む .htpasswd
ファイルを指します。
location /status { auth_basic "Access to the staging site"; auth_basic_user_file /etc/apache2/.htpasswd; }
URL 内の認証情報を使用したアクセス
多くのクライアントでは次のように、ユーザー名とパスワードを含むエンコードされた URL を使用してログインプロンプトを回避できます。
https://username:password@www.example.com/
これらの URL の使用は推奨されていません。Chrome ではセキュリティ上の理由から、URL の username:password@
部分も削除されます。 Firefox ではサイトが実際に認証を要求するかどうかをチェックし、そうでない場合 Firefox はユーザーに「"username" というユーザー名で "www.example.com" というサイトにログインしようとしていますが、ウェブサイトは認証を必要としません。これはあなたを騙そうとしている可能性があります。」と警告します。