CORS を利用した Azure CDN の使用

CORS とは

CORS (クロス オリジン リソース共有) は、あるドメインで実行されている Web アプリケーションが別のドメイン内にあるリソースにアクセスできるようにする HTTP 機能です。 クロスサイト スクリプティング攻撃の可能性を低減させるために、すべての最新の Web ブラウザーには 同一オリジン ポリシーと呼ばれるセキュリティ制限が実装されています。 この制限により、Web ページは他のドメイン内の API を呼び出すことができません。 CORS を使用すれば、あるオリジン (オリジン ドメイン) から他のオリジン内の API を安全に呼び出すことができます。

しくみ

CORS 要求には、"簡単な要求" と "複雑な要求" の 2 種類があります。

単純な要求の場合:

  1. ブラウザーが、追加の Origin HTTP 要求ヘッダーを含む CORS 要求を送信します。 この要求ヘッダーの値は親ページを提供したオリジンであり、"プロトコル"、"ドメイン"、"ポート" の組み合わせとして定義されます。HTTPS://www.contoso.com からのページが fabrikam.com オリジンのユーザーのデータにアクセスしようとすると、次の要求ヘッダーが fabrikam.com に送信されます。

    Origin: https://www.contoso.com

  2. サーバーからの応答では次のいずれかのヘッダーが返される場合があります。

    • 許可されるオリジン サイトを示す、応答の Access-Control-Allow-Origin ヘッダー。 次に例を示します。

      Access-Control-Allow-Origin: https://www.contoso.com

    • 403 などの HTTP エラー コード (Origin ヘッダーの確認後、サーバーによってクロス オリジン要求が許可されなかった場合)

    • すべてのオリジンを許可するワイルドカードが含まれる Access-Control-Allow-Origin ヘッダー。

      Access-Control-Allow-Origin: *

複雑な要求:

複雑な要求は CORS 要求です。この要求で、ブラウザーは実際の CORS 要求を送信する前に、"プレフライト要求" (準備プローブ) を送信します。 プレフライト要求は、サーバーのアクセス許可に対して、元の CORS 要求が処理を実行できるかどうかと、その要求が、同じ URL への OPTIONS 要求かどうかを尋ねます。

ヒント

CORS フローおよびよくある落とし穴の詳細については、CORS for REST API ガイドを参照してください。

ワイルドカードまたは単一のオリジンのシナリオ

Azure CDN の CORS は、Access-Control-Allow-Origin ヘッダーがワイルドカード (*) または単一のオリジンに設定されているときは、追加の構成なしで自動的に動作します。 最初の応答が CDN によってキャッシュされ、以降の要求で同じヘッダーが使用されます。

オリジンに CORS が設定される前に CDN に対し要求が行われている場合、エンドポイント コンテンツのコンテンツを消去して、Access-Control-Allow-Origin ヘッダーでそのコンテンツを再度読み込む必要があります。

複数のオリジンのシナリオ

複数のオリジンを CORS で許可する必要がある場合は、若干複雑になります。 最初の CORS オリジンの Access-Control-Allow-Origin ヘッダーが CDN にキャッシュされるときに問題が発生します。 異なる CORS オリジンが以降の要求を行ったときは、キャッシュされた Access-Control-Allow-Origin ヘッダーを CDN が提供しても一致しません。 この問題を修正するにはいくつかの方法があります。

Azure CDN Standard プロファイル

Microsoft の Azure CDN Standard では、Standard ルール エンジンでルールを作成して、要求の Origin ヘッダーを確認することができます。 オリジンが有効である場合、ルールが、Access-Control-Allow-Origin ヘッダーを目的の値に設定します。 この場合は、ファイルの配信元サーバーからの Access-Control-Allow-Origin ヘッダーは無視され、CDN のルール エンジンが、許可される CORS オリジンを完全に管理します。

Standard ルール エンジンを使用したルールの例

ヒント

追加のアクションをルールに追加して、Access-Control-Allow-Methods などの追加の応答ヘッダーを変更できます。

Azure CDN Premium from Edgio

Edgio Premium ルール エンジンを使用する場合、要求の Origin ヘッダーを確認するための ルールを作成 する必要があります。 オリジンが有効である場合、ルールが、Access-Control-Allow-Origin ヘッダーを要求に指定されているオリジンに設定します。 Origin ヘッダーで指定されたオリジンが許可されない場合、ルールにより Access-Control-Allow-Origin ヘッダーを省略する必要があります。その結果、ブラウザーが要求を拒否します。

Premium ルール エンジンを使用してこの問題を解決する方法は 2 つあります。 どちらの場合でも、ファイルの配信元サーバーからの Access-Control-Allow-Origin ヘッダーは無視され、CDN のルール エンジンが、許可される CORS オリジンを完全に管理します。

有効なオリジンがすべて含まれる 1 つの正規表現

この場合、許可するオリジンがすべて含まれた正規表現を作成します。

https?:\/\/(www\.contoso\.com|contoso\.com|www\.microsoft\.com|microsoft.com\.com)$

ヒント

Azure CDN Premium from Edgio では、正規表現を作成するエンジンとして Perl Compatible Regular Expressions を使用します。 正規表現を検証するには、Regular Expressions 101 などのツールを使用できます。 スラッシュ (/) は正規表現で有効であり、エスケープする必要はありません。ただし、この文字のエスケープはベスト プラクティスだと考えられており、一部の正規表現検証ツールではエスケープするよう想定されていることに注意してください。

正規表現に一致すると、ルールが、オリジンの Access-Control-Allow-Origin ヘッダーが (存在する場合)、要求の送信元のオリジンに置き換えられます。 Access-Control-Allow-Methods などの追加の CORS ヘッダーを追加することもできます。

Rules example with regular expression

オリジンごとの要求ヘッダー ルール

正規表現を使用するのではなく、許可するオリジンごとに個別のルールを作成することもできます。この場合、Request Header Wildcard (要求ヘッダーのワイルドカード)一致条件を使用します。 正規表現の方法と同様に、ルール エンジンは単独で CORS ヘッダーを設定します。

Rules example without regular expression

ヒント

この例では、ワイルドカード文字 * により、HTTP と HTTPS の両方を照合するようにルール エンジンに指示しています。