Azure Storage に対するクロスオリジン リソース共有 (CORS) のサポート
バージョン 2013-08-15 以降の Azure ストレージ サービスでは、BLOB、テーブル、およびキューの各サービスでクロス オリジン リソース共有 (CORS) をサポートしています。 ファイル サービスは、バージョン 2015-02-21 以降の CORS をサポートしています。
CORS は、あるドメインで実行されている Web アプリケーションが別のドメイン内にあるリソースにアクセスできるようにする HTTP 機能です。 Web ブラウザーには、Web ページで別のドメインの API を呼び出すことができないようにする同一呼び出し元ポリシーと呼ばれるセキュリティ制限が実装されています。CORS を使用すると、あるドメイン (元のドメイン) から別のドメインの API を安全に呼び出すことができます。 CORS の詳細については、CORS の仕様を参照してください。
BLOB サービスのプロパティの設定、ファイル サービスのプロパティの設定、キュー サービスのプロパティの設定、および TableService プロパティの設定を呼び出すことで、各 Azure Storage サービスに対して CORS ルールを個別に設定できます。 サービスに対して CORS ルールを設定した場合、別のドメインからサービスに対して行われた要求が正しく承認されると、指定したルールに従ってその要求を許可するかどうかが評価されます。
重要
CORS は承認メカニズムではありません。 CORS が有効になっているときにストレージ リソースに対して行われた要求は、有効な承認ヘッダーを持っているか、パブリック リソースに対して行う必要があります。
CORS は、Premium パフォーマンス レベルの汎用 v1 または v2 ストレージ アカウントを除く、すべてのストレージ アカウントの種類でサポートされています。
CORS 要求について
元のドメインからの CORS 要求は、次の 2 つの異なる要求で構成されている場合があります。
サービスによって課されている CORS の制限を照会するプレフライト要求。 要求メソッドが 簡単なメソッド(つまり、GET、HEAD、POST) でない場合は、プレフライト要求が必要です。
目的のリソースに対して行う実際の要求。
プレフライト要求
プレフライト要求では、アカウント所有者がストレージ サービスに対して設定した CORS の制限を照会します。 Web ブラウザー (または他のユーザー エージェント) は、要求ヘッダー、メソッド、元のドメインを含む OPTIONS 要求を送信します。 ストレージ サービスでは、あらかじめ構成された一連の CORS ルールに基づいて目的の操作を評価します。CORS ルールには、ストレージ リソースに対する実際の要求で指定できる元のドメイン、要求メソッド、要求ヘッダーを指定します。
CORS がサービスに対して有効になっており、プレフライト要求と一致する CORS ルールがある場合、サービスはステータス コード 200 (OK) で応答し、必要な Access-Control ヘッダーを応答に含めます。
CORS がサービスに対して有効になっていない場合、またはプレフライト要求と一致する CORS ルールがない場合、サービスはステータス コード 403 (Forbidden) で応答します。
OPTIONS 要求に必須の CORS ヘッダー (Origin ヘッダーと Access-Control-Request-Method ヘッダー) が含まれていない場合、サービスはステータス コード 400 (Bad request) で応答します。
プレフライト要求は、要求されたリソースではなく、サービス (BLOB、ファイル、キュー、またはテーブル) に対して評価されることに注意してください。 要求を成功させるには、アカウント所有者が適切なアカウント サービス プロパティを設定して CORS を有効にしている必要があります。
実際の要求
プレフライト要求が受け入れられ、応答が返されると、ブラウザーはストレージ リソースに対する実際の要求をディスパッチします。 プレフライト要求が拒否されると、ブラウザーは実際の要求を直ちに拒否します。
実際の要求は、ストレージ サービスに対する通常の要求として扱われます。 Origin ヘッダーが存在する場合は要求が CORS 要求であることを示しており、サービスは一致する CORS ルールを確認します。 一致が見つかった場合は、Access-Control ヘッダーを応答に追加し、クライアントに送り返します。 一致が見つからない場合は、CORS Access-Control ヘッダーを返しません。
Azure Storage の CORS の有効化
CORS ルールはサービス レベルで設定されるため、サービス (BLOB、ファイル、キュー、テーブル) ごとに CORS を個別に有効または無効にする必要があります。 既定では、各サービスの CORS は無効になっています。 CORS を有効にするには、BLOB、Queue、Table サービス、またはバージョン 2015-02-21 または File サービスのバージョン 2013-08-15 以降を使用して、適切なサービス プロパティを設定する必要があります。 CORS を有効にするには、サービス プロパティに CORS ルールを追加します。 サービスの CORS を有効または無効にする方法と CORS ルールを設定する方法の詳細については、「Blob Service のプロパティの設定」、「ファイル サービスのプロパティの設定」、「Table Service のプロパティの設定」、および「キュー サービスのプロパティの設定」を参照してください。
操作で指定された単一の CORS ルールのサンプルを次に Set Service Properties
示します。
<Cors>
<CorsRule>
<AllowedOrigins>http://*.contoso.com, http://www.fabrikam.com</AllowedOrigins>
<AllowedMethods>PUT,GET</AllowedMethods>
<AllowedHeaders>x-ms-meta-data*,x-ms-meta-target*,x-ms-meta-abc</AllowedHeaders>
<ExposedHeaders>x-ms-meta-*</ExposedHeaders>
<MaxAgeInSeconds>200</MaxAgeInSeconds>
</CorsRule>
<Cors>
CORS ルールに含まれている各要素は次のとおりです。
AllowedOrigins: CORS を使用したストレージ サービスに対する要求が許可される元のドメイン。 元のドメインとは、要求が発行されたドメインです。 元のドメインは、ユーザー エージェントがサービスに送信した元のドメインと、大文字と小文字の違いも含めて正確に一致する必要があります。
指定したドメインの代わりにワイルドカード文字 '*' を使用して、すべての配信元ドメインが CORS 経由で要求を行えるようにすることができます。 サブドメインの代わりにワイルドカード文字を使用して、特定のドメインのすべてのサブドメインが CORS 経由で要求を行えるようにすることもできます。 上記の例では、 のすべてのサブドメイン
contoso.com
が CORS を介して要求を行うことができますが、 のfabrikam.com
サブドメインからのwww
要求のみが CORS 経由で許可されています。AllowedMethods: 元のドメインが CORS 要求で使用できるメソッド (HTTP 要求の動詞)。 上記の例では、PUT 要求と GET 要求のみが許可されます。
AllowedHeaders: 元のドメインが CORS 要求に指定できる要求ヘッダー。 上記の例では、
x-ms-meta-data
、x-ms-meta-target
、およびx-ms-meta-abc
で始まるすべてのメタデータ ヘッダーが許可されます。 ワイルドカード文字 '*' は、指定したプレフィックスで始まるすべてのヘッダーが許可されることを示しています。ExposedHeaders: CORS 要求への応答で送信され、ブラウザーが要求の発行元に公開できる応答ヘッダー。 上記の例では、
x-ms-meta
で始まるすべてのヘッダーを公開するようブラウザーに指示しています。MaxAgeInSeconds: ブラウザーがプレフライト OPTIONS 要求をキャッシュする最大時間。
Azure ストレージ サービスでは、AllowedHeaders と ExposedHeaders の両方の要素に、プレフィックスが指定されたヘッダーを指定できます。 ヘッダーのカテゴリを許可するには、そのカテゴリに共通するプレフィックスを指定します。 たとえば、プレフィックスが指定されたヘッダーとして x-ms-meta*
を指定すると、x-ms-meta
で始まるすべてのヘッダーと一致するルールが設定されます。
CORS ルールには、次の制限事項が適用されます。
ストレージ サービス (BLOB、ファイル、テーブル、キュー) ごとに最大 5 つの CORS ルールを指定できます。
XML タグを除く要求のすべての CORS ルール設定の最大サイズは、2 KiB を超えないようにしてください。
許可されるヘッダー、公開されるヘッダー、許可される元のドメインの長さは、256 文字を超えることはできません。
許可されるヘッダーと公開されるヘッダーとして、次のいずれかを使用できます。
- リテラル ヘッダー。x-ms-meta-processed などの正確なヘッダー名を指定します。 最大 64 個のリテラル ヘッダーを要求で指定できます。
- プレフィックス付きヘッダー。 x-ms-meta-data* など、ヘッダーのプレフィックスが指定されます。 このような方法でプレフィックスを指定した場合は、指定のプレフィックスで始まるすべてのヘッダーが許可または公開されます。 最大 2 個のプレフィックスが指定されたヘッダーを要求で指定できます。
AllowedMethods 要素で指定されたメソッド (または HTTP 動詞) は、Azure ストレージ サービス API でサポートされるメソッドに従う必要があります。 サポートされているメソッドは、DELETE、GET、HEAD、MERGE、POST、PATCH、OPTIONS、PUT です。
CORS ルールの評価ロジックについて
ストレージ サービスでは、プレフライト要求や実際の要求を受け取ると、適切なサービス プロパティ設定操作でサービスに設定された CORS ルールに基づいてその要求を評価します。 CORS ルールは、サービス プロパティ設定操作の要求本文に設定された順序で評価されます。
CORS ルールは、次のように評価されます。
まず、要求の元のドメインが
AllowedOrigins
要素に指定されているドメインの一覧と照合されます。 元のドメインが一覧に含まれている場合、またはワイルドカード文字 '*' によってすべてのドメインが許可されている場合、ルールの評価は次に進みます。 元のドメインが含まれていない場合、要求は失敗します。次に、要求のメソッド (HTTP 動詞) が
AllowedMethods
要素に指定されているメソッドの一覧と照合されます。 メソッドが一覧に含まれている場合、ルールの評価は次に進みます。含まれていない場合、要求は失敗します。要求が、要求の元のドメインとメソッドのルールと一致した場合、要求を処理するためにそのルールが選択され、それ以降のルールは評価されません。 ただし、要求が成功する前に、要求に指定されているヘッダーが
AllowedHeaders
要素に指定されているヘッダーの一覧と照合されます。 送信したヘッダーが許可されるヘッダーと一致しない場合、要求は失敗します。
ルールは要求本文に含まれている順序で処理されるため、元のドメインに関する最も制限の厳しいルールを一覧の先頭に指定して、そのルールが最初に評価されるようにすることをお勧めします。 制限の緩いルール (すべての元のドメインを許可するルールなど) は一覧の末尾に指定します。
例 – CORS ルールの評価
次の例では、ストレージ サービスに CORS ルールを設定する操作の要求本文の一部を示しています。 要求の構築の詳細については、「 Blob Service のプロパティの 設定」、「ファイル サービスのプロパティの 設定」、「キュー サービスのプロパティの設定」、および 「Table Service のプロパティの設定 」を参照してください。
<Cors>
<CorsRule>
<AllowedOrigins>http://www.contoso.com</AllowedOrigins>
<AllowedMethods>PUT,HEAD</AllowedMethods>
<MaxAgeInSeconds>5</MaxAgeInSeconds>
<ExposedHeaders>x-ms-*</ExposedHeaders>
<AllowedHeaders>x-ms-blob-content-type, x-ms-blob-content-disposition</AllowedHeaders>
</CorsRule>
<CorsRule>
<AllowedOrigins>*</AllowedOrigins>
<AllowedMethods>PUT,GET</AllowedMethods>
<MaxAgeInSeconds>5</MaxAgeInSeconds>
<ExposedHeaders>x-ms-*</ExposedHeaders>
<AllowedHeaders>x-ms-blob-content-type, x-ms-blob-content-disposition</AllowedHeaders>
</CorsRule>
<CorsRule>
<AllowedOrigins>http://www.contoso.com</AllowedOrigins>
<AllowedMethods>GET</AllowedMethods>
<MaxAgeInSeconds>5</MaxAgeInSeconds>
<ExposedHeaders>x-ms-*</ExposedHeaders>
<AllowedHeaders>x-ms-client-request-id</AllowedHeaders>
</CorsRule>
</Cors>
次に、以下の CORS 要求について考えてみましょう。
Method | 出発地 | 要求ヘッダー | ルールの一致 | 結果 |
---|---|---|---|---|
PUT | http://www.contoso.com |
x-ms-blob-content-type |
最初のルール | Success |
GET | http://www.contoso.com |
x-ms-blob-content-type |
2 番目のルール | Success |
GET | http://www.contoso.com |
x-ms-client-request-id |
2 番目のルール | 障害 |
最初の要求は最初のルールと一致します (元のドメインが許可される元のドメインと一致し、メソッドが許可されるメソッドと一致し、ヘッダーが許可されるヘッダーと一致します)。そのため、成功します。
2 番目の要求は、メソッドが許可されるメソッドと一致しないため、最初のルールと一致しません。 しかし、2 番目のルールと一致するため、成功します。
3 番目の要求は、元のドメインとメソッドが 2 番目のルールと一致します。そのため、それ以降のルールは評価されません。 ただし、x-ms-client-request-id
ヘッダーが 2 番目のルールでは許可されていません。そのため、3 番目のルールのセマンティクスであれば成功するものの、要求は失敗します。
注意
この例では制限の緩いルールが制限の厳しいルールよりも前に指定されていますが、通常は、最も制限の厳しいルールを一覧の先頭に指定することをお勧めします。
Vary ヘッダーの設定方法について
Vary
ヘッダーは、要求を処理するためにサーバーによって選択された条件についてブラウザーまたはユーザー エージェントにアドバイスする一連の要求ヘッダー フィールドで構成された標準 HTTP/1.1 ヘッダーです。
Vary
ヘッダーは、主にプロキシ、ブラウザー、および CDN がキャッシュする際に応答のキャッシュ方法を決定するために使用します。 詳細については、 Vary ヘッダーの仕様をご覧ください。
ブラウザーまたは別のユーザー エージェントでは、CORS 要求の応答をキャッシュする際に、元のドメインを許可される元のドメインとしてキャッシュします。 キャッシュがアクティブな間に 2 つ目のドメインがストレージ リソースに対して同じ要求を発行した場合、ユーザー エージェントはキャッシュされている元のドメインを取得します。 2 つ目のドメインはキャッシュされているドメインと一致しないため、要求は失敗します (一致する場合は成功します)。 場合によっては、要求元ドメインが Vary
キャッシュされた配信元と異なる場合に、後続の CORS 要求をサービスに送信するようにユーザー エージェントに指示するように、Azure Storage によって ヘッダー Origin
が に設定されます。
Azure Storage では、次のVary
場合にOrigin
、実際の GET/HEAD 要求のヘッダーが に設定されます。
要求元のドメインと CORS ルールで定義されている許可される元のドメインが完全に一致する。 完全に一致するためには、CORS ルールにワイルドカード文字 "*" が含まれていない必要があります。
要求元のドメインと一致するルールはないが、ストレージ サービスに対して CORS が有効になっている。
GET/HEAD 要求がすべての元のドメインを許可する CORS ルールと一致する場合、応答はすべての元のドメインが許可されていることを示し、ユーザー エージェントのキャッシュがアクティブな間は、すべての元のドメインからの後続の要求が許可されます。
GET/HEAD 以外のメソッドに対する応答はユーザー エージェントによってキャッシュされないため、これらのメソッドを使用する要求では、ストレージ サービスが Vary
ヘッダーを設定することはありません。
前に説明した例に基づいて、Azure ストレージが GET/HEAD 要求にどのように応答するかを次の表に示します。
要求に Origin ヘッダーが存在する | このサービスに CORS ルールが指定されている | すべての配信元 (*) を許可する照合ルールが存在します | 元のドメインと完全に一致する照合ルールが存在する | Origin に設定された Vary にヘッダーが応答に含まれている | 応答には Access-Control-Allowed-Origin が含まれます: "*" | Access-Control-Exposed-Headers が応答に含まれている |
---|---|---|---|---|---|---|
いいえ | いいえ | いいえ | いいえ | いいえ | いいえ | いいえ |
いいえ | はい | いいえ | いいえ | はい | いいえ | いいえ |
いいえ | はい | はい | いいえ | いいえ | はい | はい |
はい | いいえ | いいえ | いいえ | いいえ | いいえ | いいえ |
はい | はい | いいえ | はい | はい | いいえ | はい |
はい | はい | いいえ | いいえ | はい | いいえ | いいえ |
はい | はい | はい | いいえ | いいえ | はい | はい |
CORS 要求への課金
アカウントのストレージ サービスに対して CORS を有効にした場合 ([Blob Service プロパティの設定]、[キュー サービス のプロパティの設定]、[ファイル サービス プロパティの設定]、または [テーブル サービス プロパティの設定] を呼び出すことによって)、正常なプレフライト要求が課金されます。 費用を最小限に抑えるには、エージェント ユーザーが要求をキャッシュするよう、CORS ルールの MaxAgeInSeconds
要素に大きい値を設定することを検討してください。
失敗したプレフライト要求に対しては課金されません。