Mio Tsuchihashi

CORSヘッダの設定方法について

Blog Post created by Mio Tsuchihashi Employee on Jul 4, 2016

近年、サイトを配信しているメインのドメインとは異なるドメインから

サイト内のリソースを配信しているお客様が増えています。

例えばCSSスタイルシートや画像、スクリプトといったリソースを別のドメインから読み込んでいたり、

AJAXを利用して別ドメインから一部のデータを取得しているといったケースもあります。

 

しかしブラウザがスクリプトから他のドメインにリクエストを送信させるということは、

悪意のあるスクリプトによって予期しないサイトにリクエストを送られてしまうなど、

セキュリティ上の懸念があります。

 

上記の理由からブラウザはスクリプトから発行されるクロスオリジンHTTPリクエストを制限しているため、

XMLHttpRequestでクロスオリジンHTTPリクエストを利用する場合、

Cross-origin resource sharing (CORS)ヘッダが必要になります。

 

本記事ではAkamaiを利用してCORSヘッダを有効化する方法について記載します。

 

CORSヘッダとは?

 

Cross-origin resource sharing (CORS)はWebサーバがドメインをまたいでリソースを配信するために、

W3Cによって勧告されたアクセス制御の仕組みです。リソースを提供するサーバが、どのサーバに対して自身のリソース利用を許可するかを示すHTTP ヘッダを追加することによって動作します。この仕組みの中で定義されたHTTPヘッダの事をCORSヘッダと呼びます。

 

CORSヘッダの有無による動作の違いを見ていきましょう。

 

下の例では、悪意のあるWebサイトがブラウザで実行されたスクリプトから

関係のない外部のリソースサーバに対してリクエストを発行させ、情報を不正に取得させようとしています。

api.example.comが認証によって守られたサーバであってもブラウザがapi.example.comに対して

認証済みであればデータを取得できてしまうことから、ブラウザに取得させた個人情報などのデータを

悪意のあるWebサーバに送信させようとしています。

しかしブラウザはSame Origin Policyに従って異なるドメインへのリクエストとレスポンスを

チェックしているため、このリクエストはブロックされます。


このようにSame Origin Policyによって不正なリクエストが防がれますが、

正規のリソースサーバに対するクロスオリジンHTTPリクエストも同じようにブロックされてしまいます。

そのため別ドメインからクロスオリジンHTTPリクエストを使用してリソースを利用させる際には

CORSに従ってリソースサーバのレスポンスにCORSヘッダを付加し、アクセスを許可する必要があります。

 

下の例では、オリジンサーバが別ドメインを持つリソースサーバよりAPIを呼び出し、

ページの表示に利用するデータを取得させようとしています。

リソースサーバはレスポンスにCORSヘッダ(Access-Control-Allow-Origin: http://www.example.com) を

付けて http://www.example.com によるリソースの利用を許可しているため、

ブラウザはこのレスポンスをブロックせずページを表示することができます。

 

 

CORSには以下のようなレスポンスヘッダが定義されています。

Header NameDescription
Access-Control-Allow-Originアクセスを許可するURI
Access-Control-Expose-Headersブラウザが使用できるヘッダのホワイトリスト
Access-Control-Max-Ageプリフライトリクエスト※のレスポンスをキャッシュする期間
Access-Control-Allow-Credentials

クレデンシャルを含むリクエストに対しレスポンスの開示を許可するか

Access-Control-Allow-Methods

プリフライトリクエスト※へのレスポンスとして用いる。

実際のリクエストで許可するメソッド

Access-Control-Allow-Headers

プリフライトリクエスト※へのレスポンスとして用いる。

実際のリクエストで許可するヘッダ

※クロスオリジンHTTPリクエストを行う前に、クロスオリジンHTTPリクエストが可能か確認するリクエスト

 

CORSについては下記のサイトで詳しく解説されていますので、併せてご参照ください。

 

MDN - HTTP アクセス制御 (CORS)

https://developer.mozilla.org/ja/docs/HTTP_access_control

 

これらのCORSヘッダを利用してクロスオリジンHTTPリクエストを許可する場合に、

リソースサーバの設定を変更してCORSヘッダをレスポンスに付加することも可能ですが、

リソースサーバを変更せず、EdgeサーバでCORSヘッダを付加することができます。

 

www.example.com が api.example.com からリソースを取得出来るように

下記の方法でapi.example.com にCORSヘッダを追加する設定をします。

 

設定方法:

Akamaiを利用してCORSヘッダを付加するにあたって、リソースサーバの配信設定を変更する必要があります。

Property Managerで下記の手順を実施して下さい。

 

1. 「Add Rule」ボタンを押す

Edit : v1 : mtsuchih-amd.example.com : Luna Property Manager 2016-06-30 19-17-05.jpg

 

2. Default Templatesの「Protection」カテゴリより「CORS (Cross Origin Resource Sharing) Headers」を選択し

「Insert Rule」ボタンを押す

 

Edit : v1 : mtsuchih-amd.example.com : Luna Property Manager 2016-06-30 19-19-37.jpg

Edit : v1 : mtsuchih-amd.example.com : Luna Property Manager 2016-06-30 19-21-10.jpg

 

3. 2で追加されたルールの内容を要件通りに修正する

 

※ Modify Outgoing Response HeaderはEdgeサーバからクライアントに返されるレスポンスに対し、

指定されたヘッダを追加・削除・変更するためのBehaviorです。

Edgeサーバを多段化している場合など、同一のヘッダが複数付加されてしまうことがあるので

単一のヘッダを付加する場合はAvoid Duplicate HeadersをYesにし、

ヘッダが重複しないように設定することを推奨します。

 

設定が完了したらStaging環境を利用してCORSヘッダが正しく付加されていることを確認してみましょう。

※Staging環境を利用したテスト方法についてはこちらの記事をご覧ください)

 

HTTP/1.1 200 OK

Server: Apache

Connection: keep-alive

Content-Type: text/html; charset=iso-8859-1

Content-Length: 16

access-control-max-age: 86400

Access-Control-Allow-Credentials: true

access-control-expose-headers: Server,range,hdntl,hdnts

Access-Control-Allow-Headers: origin,range,hdntl,hdnts

Access-Control-Allow-Methods: GET,POST,OPTIONS

Access-Control-Allow-Origin: http://www.example.com

X-Akamai-Staging: EdgeSuite

X-Check-Cacheable: YES

....

Outcomes