クロスドメイン制約とBASIC認証
初めての技術系ブログです。
ご不明な点がありましたら、お気軽にコメント欄へ記入ください。
初回は「ドメイン X のサイトから、異なるドメイン Y の BASIC 認証つきのサイトにアクセスできるのか 」について検証した結果を書きたいと思います。 検証結果としては、
- ブラウザのセキュリティ設定を On にしていればアクセスできません。
- ブラウザのセキュリティ設定を Off にしていればアクセス出来ます。
以下でその理由について下記の流れで説明していきます。
BASIC 認証について
まず BASIC 認証とは、HTTP で定義される認証方式の一つです。
認証の仕方としてはブラウザ側で「ユーザ名:パスワード」を Base64 でエンコードして、サーバー側へ送信します。
サーバー側では受信した Base64 のデータをデコードし、ユーザー名とパスワードを取得して、認証を行う処理方式のことを指します。
クロスドメイン制約について
2 つ目にクロスドメイン制約とは、「ブラウザ上で実行される JavaScript は同じドメインにしかリクエストの送信やクッキーの編集を行えない」という制限のことです。
この制限がある理由は、あるサイトから悪意のあるサイトに勝手にアクセスできないようにするためです。 もし、あるサイトから異なるドメインのサイトへアクセスしたい場合は、次の2つの方法があります。
- HTTP のリクエストヘッダに許可する外部ドメインを設定する方法
- JSONP(JSON with padding)
1 つ目の方法は、HTTP のリクエストヘッダ「Access-Control-Allow-Origin」に、外部ドメインを設定する方法です。
2 つ目の方法は、あるドメイン X のサイトに JavaScript を置き、その場所をドメイン Y のサイトにあらかじめ教えておきます。ドメイン Y からドメイン X の JavaScript を取得・実行すると、結果としてドメイン Y からドメイン X のサイト内のデータにアクセスできるという方法です。
今回は方法 1 で実現できる方法について検証します。
方法 2 の JSONP は、ここでは詳しく説明しませんが、JSONP インジェクションという攻撃を受ける可能性があるため、方法 1 を採用します。
CORS(Cross Origin Resource Sharing)について
CORS(Cross Origin Resource Sharing)は、JavaScript でクロスドメインにアクセスする方法です。さきほど述べていたドメインとオリジンはほぼ同義です。 クロスしている(異なる)オリジン(≒ ドメイン)とリソースをシェアする方法です。
CORS では、JavaScript で異なるドメインにアクセスする際に、シンプルなリクエストでない場合、preflight リクエストと呼ばれる通信がなされます。 preflight リクエストとは、アクセスの許可設定を確認するための通信です。 preflight リクエストが送られる条件についてはCORS(Cross-Origin Resource Sharing)について整理してみた | DevelopersIOをご覧ください。
CORS の動作の流れは主に2パターンあり、以下で説明します。
【操作・設定の前提】
- ブラウザは現在 aaa.com に接続している。
- サイト(aaa.com)から別のドメインのサイト(bbb.com)にアクセスする。
- bbb.com では、aaa.com からのアクセス許可設定をしている。
- preflight リクエストなしの場合
- ブラウザが bbb.com にリクエストを送信する。
- aaa.com が bbb.com へのアクセスを許可しているため、ブラウザは欲しかった情報を bbb.com から取得できる。
- preflight リクエストありの場合
- ブラウザから bbb.com に prefight リクエストを送信する。
- bbb.com が aaa.com からのアクセス許可設定を確認し、確認結果をブラウザに送信する。
- 確認結果が良ければ、ブラウザは bbb.com にリクエストを送信する。
- bbb.com はブラウザにレスポンスを送信する。
パターン ① の場合は 1 往復で済むのに対し、パターン ② の場合は確認作業があるため、2 往復必要ということになります。
ただし、ブラウザのセキュリティ設定が Off であれば preflight リクエストで確認しないため、いずれの場合も必ず 1 往復になります。(preflight リクエストは安全を担保するための確認処理であるため、セキュリティ設定を Off にすれば発生しない。)
BASIC 認証つき CORS について
最後に本記事の目的である BASIC 認証つき CORS について説明します。
先ほどの環境の前提に、1 つ条件を加えます。
【操作・設定の前提】
- ブラウザは現在 aaa.com に接続している。
- サイト(aaa.com)から別のドメインのサイト(bbb.com)にアクセスする。
- bbb.com では、aaa.com からのアクセス許可設定をしている。
- 【追加条件】: アクセス先の bbb.com に BASIC 認証をかけている。
この状態の時に、CORS が可能かどうかについて述べます。
- BASIC 認証情報付きの CORS(Authorization ヘッダ付き)
- ブラウザから bbb.com へのアクセスは、Authorization ヘッダつきであるため、まず preflight リクエストを送信します。
- preflight リクエストには Authorization ヘッダは付いていないため、bbb.com 側では BASIC 認証が解除できず、認証エラーをブラウザに返します。
- ブラウザは bbb.com へアクセス出来ずに通信終了となる。
- BASIC 認証情報なしの CORS(Authorization ヘッダなし)
- ブラウザから bbb.com へアクセスします。
- bbb.com で BASIC 認証が解除できず、認証エラーとなりブラウザへ返します。
- ブラウザは bbb.com へアクセス出来ずに処理終了となる。
上記理由で、通常であればいずれの場合であっても Basic 認証付き CORS はできません。
しかし、ブラウザのセキュリティ設定が Off であれば、パターン ① は以下のように変わり、Basic 認証付き CORS ができるようになる。
※ブラウザのセキュリティ設定が Off であれば preflight が発生しない。
- BASIC 認証情報付きの CORS(Authorization ヘッダ付き)
- ブラウザは aaa.com から JavaScript を取得し、bbb.com へ XMLHttpRequest が実行される。[Authorization ヘッダつきであるが、preflight リクエストは発生しない。]
- ブラウザから Authorization ヘッダ付きリクエストが bbb.com へ送られる。
- Authorization ヘッダにユーザーとパスワードの情報があるため、bbb.com で BASIC 認証が解除され、ブラウザに正常時のレスポンスを返します。
- ブラウザは bbb.com からレスポンスを受け取り、正常終了となる。
以上より、冒頭でも記載しましたが、以下のような結果となります。
- ブラウザのセキュリティ設定を On にしていればアクセスできません。
- ブラウザのセキュリティ設定を Off にしていればアクセス出来ます。
ここまで読んで下さりありがとうございました。