Quantcast
Channel: Infragistics Blogs
Viewing all articles
Browse latest Browse all 218

ASP.NET Web API で CORS を有効にする

$
0
0

原文: Dhananjay Kumar » How to Enable CORS in the ASP.NET Web API

Ultimate_banner152c

以下のエラーを見たことがありますか?

Cross-origin Request Blocked. The same origin policy disallows reading the resource”.

このエラーはリソースを共有する際に CORS のサポートがない場合に発生します。これは origin B にある Web アプリケーションで origin A の Web API を利用しようとするときに起こります。このエラーを解決するには CORS を十分に理解する必要があります。

このブログの目的は ASP.NET Web API で CORS を有効にする実用的な実装についてご紹介することですが、理論上の概念にも触れておきます。CORS は Cross-Origin Resource-Sharing の略語です。セキュリティ上の理由により、ユーザーエージェントが同じ origin に属しない場合リソースを共有できません。ユーザーエージェント例はブラウザー、HTML ドキュメント、スクリプトおよび XMLHttpRequest です。

Cross-Origin および Same-Origin の概念を見てみましょう。Origin の概念は RF 6454 で定義されました。2 つの URL は同一生成元と呼ばれるには以下の項目が同じである必要があります:

  1. スキーム (http)
  2. ホスト (server)
  3. ポート (8888)

Origin (生成元) は スキーム、 ホスト、 および Port 番号で構成されます。

clip_image001

2 つのリソースがスキーム、ホストおよびポートが同じの場合、そのリソースは同一生成元ですが、同じでない場合のリソースは異なる生成元です。以下の URI を見てみましょう。

http://abc.com:80http://xyz.com:8080はホストとポート番号が同じではないので生成元は異なります。セキュリティ上の理由により、これらの URL 間のリソース共有は制限される場合があります。XMLHttpRequest の例で CORS を考察してみましょう。HTML ドキュメントからサーバーで HTTP 操作をするにはXMLHttpRequest を使用します。XMLHttpRequest で 2 つの URL が使用されます:

  1. 要求された URL またはサーバーの URL
  2. 要求を開始したドキュメントの URL

2 つの URL はスキーム、ホストおよびポートが同じである場合、XMLHttpRequest オブジェクトは操作を実行しますが、そうでない場合、セキュリティ上の理由により HTTP 要求をブロックします。

サーバーとブラウザーは CORS によるサポートが必要です。最近のブラウザーは既定で CORS をサポートしますが、API 開発者は Web API で CORS のサポートを有効する必要があります。

ASP.NET Web API での CORS

ここでは、以下の画像のようにクラスの配列を返すとてもシンプルな ASP.NET Web API を作成しました。

clip_image002

ご覧のとおり Web API は 8458 ポートで実行しています。次に、5901 ポートの URI で実行する JavaScript アプリケーションでデータを取得しようとします。

clip_image003

HTTP 呼び出しを作成するには HTML ドキュメントで XMLHttpRequest オブジェクトを使用します。Web API の URI (要求されたリソースの URI) と HTML ドキュメント (要求が生じた URL) が同じでないため生成元は異なり、 XMLHttpRequest オブジェクトはリソースの共有をブロックします。ブラウザーで以下の画像のような例外が発生される可能が高いです。

clip_image005

この問題について掘り下げてみましょう。ブラウザーで開発者ツールを開き、Network タブをクリックします。以下の画像に表示されるように Request Header で Origin および Host が見られます。これらが異なることは明らかです。CORS はユーザーエージェントで禁止されています。

clip_image007

Response Header を確認しても Access-Control-Allow-Origin に関する情報はありません。

clip_image009

サーバーはヘッダーでどの生成元がリソースへアクセスできるかの応答を送信しないため、XMLHttpRequest オブジェクトはブラウザーでのリソース共有をブロックします。次に、Web API での CORS のサポートを有効にします。

ASP.NET Web API で CORS のサポートを有効にする

ASP.NET Web API 2.0 で CORS を有効するには、まずプロジェクトに Microsoft.AspNet.WebApi.Cors パッケージを追加する必要があります。コマンド プロンプトを使用してパッケージをインストールするか、また以下の画像のように NuGet マネージャーを使用し、パッケージを検索しインストールします。

clip_image011

Web API の CORS のサポートは 3 つのレベルがあります。

  1. グローバルレベル
  2. コントローラーレベル
  3. アクションレベル

グローバル レベルで CORS のサポートを設定するには、はじめに CORS パッケージをインストールし、App_Startフォルダーにある WebApiConfig.cs ファイルを開きます。

var cors = new EnableCorsAttribute("http://localhost:5901", "*", "*");

config.EnableCors(cors);

グローバル レベルで CORS のサポートを設定した後、もう一度 Web API をホストし、要求および応答ヘッダーを検証します。また、Enable CORS の属性で Origin URL を JavaScript アプリに設定しました。

以下の画像のように Web API サーバーは余分な Access-Control-Allow-Origin ヘッダーを Response headers に追加します。Response header での Access-Control-Allow-Origin ヘッダーでの URL と Request header での Origin header での URL は同じである必要があります。この場合のみ、CORS 操作は XMLHttpRequest に許可されます。Access-Control-Allow-Orgin の Response header の値はワイルドカード文字 * に設定される場合もあります。これはサーバーが特別な生成元のみをサポートするのではなく、すべての生成元で CORS サポートをするという意味です。

clip_image013

サーバーで CORS のサポートを有効にしたので、例外が発生せず、データはブラウザーでフェッチします。

上記のように ASP.NET Web API で CORS のサポートは 3 つのレベルを設定できます。

  1. アクションレベル
  2. コントローラーレベル
  3. グローバルレベル

CORS をアクション レベルに有効する

下記のように CORS のサポートはアクション レベルで有効にできます。

[EnableCors(origins: "http://localhost:5901", headers: "*", methods: "*")]
public HttpResponseMessage GetItem(int id)
{
            // コードを追加する 
}

上記のコードで GetItem アクションの CORS を有効にしました。また、すべてのヘッダーを許可するにはパラメーターを設定し、すべての HTTP メソッドをサポートするには値をアスタリスクに設定します。

CORS をコントローラー レベルで有効にする

下記のように CORS のサポートはコントローラー レベルで有効にできます。

[EnableCors(origins: "http://localhost:5901", headers: "*", methods: "*")]
public class ClassesController : ApiController
{
}

上記のコードで Classes Controller の CORS を有効にしました。また、すべてのヘッダーを許可するにはパラメーターを設定し、すべての HTTP メソッドをサポートするには値をアスタリスクに設定します。[DisableCors] 属性で CORS のサポートのうち 1 つのアクションを除外します。

CORS をグローバル レベルで有効にする

グローバル レベルで CORS のサポートを設定するには、はじめに CORS パッケージをインストールし、App_Startフォルダーにある WebApiConfig.cs ファイルを開きます。

var cors = new EnableCorsAttribute("http://localhost:5901", "*", "*");
config.EnableCors(cors);

属性を 1 つ以上のスコープに設定する場合、優先順位は以下のようになります:

clip_image014

EnableCors の属性

EnableCors に 3 つの属性を渡すことができます:

1. Origins: コンマ区切りで 1 つ以上の生成元の値を設定できます。生成元は API に AJAX 要求をするには生成元の値をワイルドカード値であるアスタリスクに設定します。

2. Request Headers: Request header パラメーターは、許可される Request headers を指定します。いずれのヘッダーでも許可する場合は値を * に設定します。

3. HTTP Methods: methods パラメーターはリソースにアクセスできる HTTP メソッドを指定します。すべてのメソッドを許可するにはワイルドカード値の * を使用します。そうでない場合、メソッドのセットにリソースへのアクセスを許可するにはコンマ分割されたメソッド名を設定します。

すべてを 1 つにまとめて、以下のコードで 2 つの生成元、すべてのヘッダー、post および get 操作で CORS を有効にすることができます。

[EnableCors(origins: "http://localhost:5901,http://localhost:8768", headers: "*",
 methods: "post,get")]
public class ClassesController : ApiController
{
}

必要に応じて Web API に資格情報を渡し、カスタム ポリシーを作成することもできます。


Viewing all articles
Browse latest Browse all 218

Trending Articles