ASP.NET Core でのクロスオリジン要求 (CORS) を有効にするEnable Cross-Origin Requests (CORS) in ASP.NET Core

作成者: Rick AndersonBy Rick Anderson

この記事では、ASP.NET Core アプリで CORS を有効にする方法について説明します。This article shows how to enable CORS in an ASP.NET Core app.

ブラウザーのセキュリティは、web ページがその web ページを提供するものとは異なるドメインに要求を行うことを防ぎます。Browser security prevents a web page from making requests to a different domain than the one that served the web page. この制限は、同じオリジンポリシーと呼ばれます。This restriction is called the same-origin policy. 同一オリジン ポリシーは、悪意のあるサイトが別のサイトから機密データを読み取ることを防ぎます。The same-origin policy prevents a malicious site from reading sensitive data from another site. 場合によっては、他のサイトからアプリへのクロス オリジン要求を許可する可能性があります。Sometimes, you might want to allow other sites make cross-origin requests to your app. 詳細については、「 MOZILLA CORS」を参照してください。For more information, see the Mozilla CORS article.

クロスオリジンリソース共有(CORS):Cross Origin Resource Sharing (CORS):

  • は、サーバーが同じオリジンポリシーを緩めることを可能にする W3C 標準です。Is a W3C standard that allows a server to relax the same-origin policy.
  • は、CORS 緩和され security のセキュリティ機能ではありませんIs not a security feature, CORS relaxes security. CORS を許可しても、API は安全ではありません。An API is not safer by allowing CORS. 詳細については、「 CORS のしくみ」を参照してください。For more information, see How CORS works.
  • サーバーが他のユーザーを拒否している間に、一部のクロスオリジン要求を明示的に許可することを許可します。Allows a server to explicitly allow some cross-origin requests while rejecting others.
  • は、 JSONPなど、以前の手法よりも安全で柔軟性に優れています。Is safer and more flexible than earlier techniques, such as JSONP.

サンプル コードを表示またはダウンロードします (ダウンロード方法)。View or download sample code (how to download)

同じオリジンSame origin

同じスキーム、ホスト、およびポート (RFC 6454) がある場合、2つの url のオリジンは同じになります。Two URLs have the same origin if they have identical schemes, hosts, and ports (RFC 6454).

次の 2 つの URL は生成元が同じです。These two URLs have the same origin:

  • https://example.com/foo.html
  • https://example.com/bar.html

これらの Url には、前の2つの Url とは異なるオリジンがあります。These URLs have different origins than the previous two URLs:

  • 別のドメイン – https://example.nethttps://example.net – Different domain
  • https://www.example.com/foo.html – 異なるサブドメインhttps://www.example.com/foo.html – Different subdomain
  • 異なるスキーム – http://example.com/foo.htmlhttp://example.com/foo.html – Different scheme
  • 別のポート – https://example.com:9000/foo.htmlhttps://example.com:9000/foo.html – Different port

Internet Explorer は、生成元を比較するときにポートを考慮しません。Internet Explorer doesn't consider the port when comparing origins.

名前付きポリシーとミドルウェアを使用した CORSCORS with named policy and middleware

CORS ミドルウェアは、クロスオリジン要求を処理します。CORS Middleware handles cross-origin requests. 次のコードでは、指定したオリジンのアプリ全体に対して CORS を有効にします。The following code enables CORS for the entire app with the specified origin:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(MyAllowSpecificOrigins,
            builder =>
            {
                builder.WithOrigins("http://example.com",
                                    "http://www.contoso.com");
            });
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseCors(MyAllowSpecificOrigins); 

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

上記のコードでは次の操作が行われます。The preceding code:

  • ポリシー名を "_Myallow固有のオリジン" に設定します。Sets the policy name to "_myAllowSpecificOrigins". ポリシー名は任意です。The policy name is arbitrary.
  • UseCors 拡張メソッドを呼び出します。これにより CORS が有効になります。Calls the UseCors extension method, which enables CORS.
  • ラムダ式を使用して AddCors を呼び出します。Calls AddCors with a lambda expression. ラムダは、CorsPolicyBuilder オブジェクトを受け取ります。The lambda takes a CorsPolicyBuilder object. WithOriginsなどの構成オプションについては、この記事の後半で説明します。Configuration options, such as WithOrigins, are described later in this article.

AddCors メソッド呼び出しは、アプリのサービスコンテナーに CORS サービスを追加します。The AddCors method call adds CORS services to the app's service container:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("http://example.com",
                                "http://www.contoso.com");
        });
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

詳細については、このドキュメントの「 CORS ポリシーオプション」を参照してください。For more information, see CORS policy options in this document .

CorsPolicyBuilder メソッドは、次のコードに示すようにメソッドを連結できます。The CorsPolicyBuilder method can chain methods, as shown in the following code:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("http://example.com",
                                "http://www.contoso.com")
                                .AllowAnyHeader()
                                .AllowAnyMethod();
        });
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

注: URL の末尾にスラッシュ (/) を含めることはできませんNote: The URL must not contain a trailing slash (/). URL が /で終了した場合、比較は false を返し、ヘッダーは返されません。If the URL terminates with /, the comparison returns false and no header is returned.

CORS ポリシーをすべてのエンドポイントに適用するApply CORS policies to all endpoints

次のコードは、CORS ミドルウェアを使用してすべてのアプリのエンドポイントに CORS ポリシーを適用します。The following code applies CORS policies to all the apps endpoints via CORS Middleware:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Preceding code ommitted.
    app.UseRouting();

    app.UseCors();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    // Following code ommited.
}

警告

エンドポイントルーティングを使用する場合は、UseRoutingUseEndpointsの呼び出しの間で実行されるように CORS ミドルウェアを構成する必要があります。With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints. 構成が正しくないと、ミドルウェアが正常に機能しなくなります。Incorrect configuration will cause the middleware to stop functioning correctly.

次のコードは、CORS ミドルウェアを使用してすべてのアプリのエンドポイントに CORS ポリシーを適用します。The following code applies CORS policies to all the apps endpoints via CORS Middleware:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseCors();

    app.UseHttpsRedirection();
    app.UseMvc();
}

注: UseMvcする前に UseCors を呼び出す必要があります。Note: UseCors must be called before UseMvc.

ページ/コントローラー/アクションレベルで CORS ポリシーを適用するには、Razor Pages、コントローラー、アクションメソッドで Cors を有効にする方法に関するページを参照してください。See Enable CORS in Razor Pages, controllers, and action methods to apply CORS policy at the page/controller/action level.

前のコードをテストする手順については、「テスト CORS 」を参照してください。See Test CORS for instructions on testing the preceding code.

エンドポイントルーティングで Cors を有効にするEnable Cors with endpoint routing

エンドポイントルーティングでは、RequireCors の拡張メソッドのセットを使用して、エンドポイントごとに CORS を有効にすることができます。With endpoint routing, CORS can be enabled on a per-endpoint basis using the RequireCors set of extension methods.

app.UseEndpoints(endpoints =>
{
  endpoints.MapGet("/echo", async context => context.Response.WriteAsync("echo"))
    .RequireCors("policy-name");
});

同様に、すべてのコントローラーに対して CORS を有効にすることもできます。Similarly, CORS can also be enabled for all controllers:

app.UseEndpoints(endpoints =>
{
  endpoints.MapControllers().RequireCors("policy-name");
});

属性を使用して CORS を有効にするEnable CORS with attributes

[EnableCors]属性は、CORS をグローバルに適用する代わりに使用できます。The [EnableCors] attribute provides an alternative to applying CORS globally. [EnableCors] 属性は、すべてのエンドポイントではなく、選択したエンドポイントに対して CORS を有効にします。The [EnableCors] attribute enables CORS for selected end points, rather than all end points.

[EnableCors] を使用して、既定のポリシーを指定し、[EnableCors("{Policy String}")] ポリシーを指定します。Use [EnableCors] to specify the default policy and [EnableCors("{Policy String}")] to specify a policy.

[EnableCors] 属性は、次のように適用できます。The [EnableCors] attribute can be applied to:

  • Razor ページ PageModelRazor Page PageModel
  • コントローラーController
  • コントローラーアクションメソッドController action method

[EnableCors] 属性を使用して、コントローラー/ページモデル/アクションに異なるポリシーを適用できます。You can apply different policies to controller/page-model/action with the [EnableCors] attribute. [EnableCors] 属性がコントローラー/ページモデル/アクションメソッドに適用され、CORS がミドルウェアで有効になっている場合、両方のポリシーが適用されます。When the [EnableCors] attribute is applied to a controllers/page-model/action method, and CORS is enabled in middleware, both policies are applied. ポリシーを組み合わせることはお勧めしません。We recommend against combining policies. 同じアプリ内ではなく、[EnableCors] の属性またはミドルウェアを使用します。Use the [EnableCors] attribute or middleware, not both in the same app.

次のコードは、各メソッドに異なるポリシーを適用します。The following code applies a different policy to each method:

[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
    // GET api/values
    [EnableCors("AnotherPolicy")]
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "green widget", "red widget" };
    }

    // GET api/values/5
    [EnableCors]        // Default policy.
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        switch (id)
        {
            case 1:
                return "green widget";
            case 2:
                return "red widget";
            default:
                return NotFound();
        }
    }
}

次のコードでは、CORS の既定のポリシーと "AnotherPolicy"という名前のポリシーを作成します。The following code creates a CORS default policy and a policy named "AnotherPolicy":

public class StartupMultiPolicy
{
    public StartupMultiPolicy(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddDefaultPolicy(
                builder =>
                {
                   
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com");
                });

            options.AddPolicy("AnotherPolicy",
                builder =>
                {
                    builder.WithOrigins("http://www.contoso.com")
                                        .AllowAnyHeader()
                                        .AllowAnyMethod();
                });

        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

CORS を無効にするDisable CORS

[DisableCors]属性は、コントローラー/ページモデル/アクションの CORS を無効にします。The [DisableCors] attribute disables CORS for the controller/page-model/action.

CORS ポリシーのオプションCORS policy options

ここでは、CORS ポリシーで設定できるさまざまなオプションについて説明します。This section describes the various options that can be set in a CORS policy:

AddPolicyStartup.ConfigureServicesで呼び出されます。AddPolicy is called in Startup.ConfigureServices. いくつかのオプションについては、まず「 CORS のしくみ」セクションを参照してください。For some options, it may be helpful to read the How CORS works section first.

許可されるオリジンの設定Set the allowed origins

AllowAnyOrigin – では、任意のスキーム (http または https) を使用して、すべてのオリジンからの CORS 要求を許可します。AllowAnyOrigin – Allows CORS requests from all origins with any scheme (http or https). web サイトはアプリに対してクロスオリジン要求を行うことができるため、AllowAnyOrigin は安全ではありません。AllowAnyOrigin is insecure because any website can make cross-origin requests to the app.

注意

AllowAnyOriginAllowCredentials の指定は安全ではない構成であり、クロスサイト要求の偽造が発生する可能性があります。Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request forgery. アプリが両方の方法で構成されている場合、CORS サービスは無効な CORS 応答を返します。The CORS service returns an invalid CORS response when an app is configured with both methods.

注意

AllowAnyOriginAllowCredentials の指定は安全ではない構成であり、クロスサイト要求の偽造が発生する可能性があります。Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request forgery. セキュリティで保護されたアプリの場合は、クライアントがサーバーリソースへのアクセスを承認する必要がある場合は、オリジンの正確な一覧を指定します。For a secure app, specify an exact list of origins if the client must authorize itself to access server resources.

AllowAnyOrigin は、プレフライト要求と Access-Control-Allow-Origin ヘッダーに影響します。AllowAnyOrigin affects preflight requests and the Access-Control-Allow-Origin header. 詳細については、「プレフライト要求」セクションを参照してください。For more information, see the Preflight requests section.

SetIsOriginAllowedToAllowWildcardSubdomains – は、ポリシーの IsOriginAllowed プロパティを、オリジンが許可されているかどうかを評価するときに、構成されたワイルドカードドメインと一致させることができるようにする関数に設定されます。SetIsOriginAllowedToAllowWildcardSubdomains – Sets the IsOriginAllowed property of the policy to be a function that allows origins to match a configured wildcard domain when evaluating if the origin is allowed.

options.AddPolicy("AllowSubdomain",
    builder =>
    {
        builder.WithOrigins("https://*.example.com")
            .SetIsOriginAllowedToAllowWildcardSubdomains();
    });

許可される HTTP メソッドを設定するSet the allowed HTTP methods

AllowAnyMethod:AllowAnyMethod:

  • すべての HTTP メソッドを許可します。Allows any HTTP method:
  • プレフライト要求と Access-Control-Allow-Methods ヘッダーに影響します。Affects preflight requests and the Access-Control-Allow-Methods header. 詳細については、「プレフライト要求」セクションを参照してください。For more information, see the Preflight requests section.

許可された要求ヘッダーを設定するSet the allowed request headers

CORS 要求で特定のヘッダーを送信できるようにするには、 author 要求ヘッダーと呼ばれますが、WithHeaders を呼び出し、許可されているヘッダーを指定します。To allow specific headers to be sent in a CORS request, called author request headers, call WithHeaders and specify the allowed headers:

options.AddPolicy("AllowHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

すべての作成者要求ヘッダーを許可するには、AllowAnyHeaderを呼び出します。To allow all author request headers, call AllowAnyHeader:

options.AddPolicy("AllowAllHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .AllowAnyHeader();
    });

この設定は、プレフライト要求と Access-Control-Request-Headers ヘッダーに影響します。This setting affects preflight requests and the Access-Control-Request-Headers header. 詳細については、「プレフライト要求」セクションを参照してください。For more information, see the Preflight requests section.

WithHeaders によって指定された特定のヘッダーに対して CORS ミドルウェアポリシーが一致するのは、Access-Control-Request-Headers で送信されたヘッダーが WithHeadersに記載されているヘッダーと完全に一致する場合のみです。A CORS Middleware policy match to specific headers specified by WithHeaders is only possible when the headers sent in Access-Control-Request-Headers exactly match the headers stated in WithHeaders.

たとえば、次のように構成されたアプリを考えてみます。For instance, consider an app configured as follows:

app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));

Content-Language (Headernames) が WithHeadersに一覧表示されていないため、CORS ミドルウェアは次の要求ヘッダーを使用してプレフライト要求を拒否します。CORS Middleware declines a preflight request with the following request header because Content-Language (HeaderNames.ContentLanguage) isn't listed in WithHeaders:

Access-Control-Request-Headers: Cache-Control, Content-Language

アプリは200 OK応答を返しますが、CORS ヘッダーを返信しません。The app returns a 200 OK response but doesn't send the CORS headers back. そのため、ブラウザーはクロスオリジン要求を試行しません。Therefore, the browser doesn't attempt the cross-origin request.

CORS ミドルウェアでは、CorsPolicy で構成されている値に関係なく、常に Access-Control-Request-Headers の4つのヘッダーを送信できます。CORS Middleware always allows four headers in the Access-Control-Request-Headers to be sent regardless of the values configured in CorsPolicy.Headers. このヘッダーの一覧には次のものが含まれます。This list of headers includes:

  • Accept
  • Accept-Language
  • Content-Language
  • Origin

たとえば、次のように構成されたアプリを考えてみます。For instance, consider an app configured as follows:

app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));

Content-Language が常にホワイトリストに登録されているため、CORS ミドルウェアは次の要求ヘッダーを使用してプレフライト要求に正常に応答します。CORS Middleware responds successfully to a preflight request with the following request header because Content-Language is always whitelisted:

Access-Control-Request-Headers: Cache-Control, Content-Language

公開された応答ヘッダーを設定するSet the exposed response headers

既定では、ブラウザーはすべての応答ヘッダーをアプリに公開しません。By default, the browser doesn't expose all of the response headers to the app. 詳細については、「 W3C クロスオリジンリソース共有 (用語): 単純な応答ヘッダー」を参照してください。For more information, see W3C Cross-Origin Resource Sharing (Terminology): Simple Response Header.

既定で使用できる応答ヘッダーは次のとおりです。The response headers that are available by default are:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

CORS 仕様は、これらのヘッダーの単純な応答ヘッダーを呼び出します。The CORS specification calls these headers simple response headers. アプリで他のヘッダーを使用できるようにするには、WithExposedHeadersを呼び出します。To make other headers available to the app, call WithExposedHeaders:

options.AddPolicy("ExposeResponseHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .WithExposedHeaders("x-custom-header");
    });

クロスオリジン要求の資格情報Credentials in cross-origin requests

資格情報では、CORS 要求で特別な処理を行う必要があります。Credentials require special handling in a CORS request. 既定では、ブラウザーはクロスオリジン要求で資格情報を送信しません。By default, the browser doesn't send credentials with a cross-origin request. 資格情報には、cookie と HTTP 認証スキームが含まれます。Credentials include cookies and HTTP authentication schemes. クロスオリジン要求で資格情報を送信するには、クライアントで XMLHttpRequest.withCredentialstrueに設定する必要があります。To send credentials with a cross-origin request, the client must set XMLHttpRequest.withCredentials to true.

XMLHttpRequest を直接使用する:Using XMLHttpRequest directly:

var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;

JQuery の使用:Using jQuery:

$.ajax({
  type: 'get',
  url: 'https://www.example.com/api/test',
  xhrFields: {
    withCredentials: true
  }
});

FETCH APIの使用:Using the Fetch API:

fetch('https://www.example.com/api/test', {
    credentials: 'include'
});

サーバーは資格情報を許可する必要があります。The server must allow the credentials. クロスオリジンの資格情報を許可するには、AllowCredentialsを呼び出します。To allow cross-origin credentials, call AllowCredentials:

options.AddPolicy("AllowCredentials",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .AllowCredentials();
    });

HTTP 応答には Access-Control-Allow-Credentials ヘッダーが含まれています。これにより、サーバーがクロスオリジン要求の資格情報を許可していることがブラウザーに伝えられます。The HTTP response includes an Access-Control-Allow-Credentials header, which tells the browser that the server allows credentials for a cross-origin request.

ブラウザーが資格情報を送信しても、応答に有効な Access-Control-Allow-Credentials ヘッダーが含まれていない場合、ブラウザーはアプリへの応答を公開せず、クロスオリジン要求は失敗します。If the browser sends credentials but the response doesn't include a valid Access-Control-Allow-Credentials header, the browser doesn't expose the response to the app, and the cross-origin request fails.

クロスオリジンの資格情報を許可することは、セキュリティ上のリスクです。Allowing cross-origin credentials is a security risk. 別のドメインの web サイトは、ユーザーの知らないうちに、サインインしているユーザーの資格情報をユーザーの代わりにアプリに送信できます。A website at another domain can send a signed-in user's credentials to the app on the user's behalf without the user's knowledge.

また、CORS 仕様では、Access-Control-Allow-Credentials ヘッダーが存在する場合、[オリジン] を "*" (すべてのオリジン) に設定することもできます。The CORS specification also states that setting origins to "*" (all origins) is invalid if the Access-Control-Allow-Credentials header is present.

プレフライト要求Preflight requests

一部の CORS 要求については、ブラウザーは実際の要求を行う前に追加の要求を送信します。For some CORS requests, the browser sends an additional request before making the actual request. この要求はプレフライト要求と呼ばれます。This request is called a preflight request. 次の条件に該当する場合、ブラウザーはプレフライト要求をスキップできます。The browser can skip the preflight request if the following conditions are true:

  • 要求メソッドは GET、HEAD、または POST です。The request method is GET, HEAD, or POST.
  • アプリで AcceptAccept-LanguageContent-LanguageContent-Type、または Last-Event-ID以外の要求ヘッダーが設定されていません。The app doesn't set request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID.
  • Content-Type ヘッダーには、次のいずれかの値が設定されています。The Content-Type header, if set, has one of the following values:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

クライアント要求に対して設定された要求ヘッダーに適用される規則は、XMLHttpRequest オブジェクトの setRequestHeader を呼び出すことによってアプリが設定するヘッダーに適用されます。The rule on request headers set for the client request applies to headers that the app sets by calling setRequestHeader on the XMLHttpRequest object. CORS 仕様は、これらのヘッダー作成者要求ヘッダーを呼び出します。The CORS specification calls these headers author request headers. このルールは、ブラウザーが設定できるヘッダー (User-AgentHostContent-Lengthなど) には適用されません。The rule doesn't apply to headers the browser can set, such as User-Agent, Host, or Content-Length.

プレフライト要求の例を次に示します。The following is an example of a preflight request:

OPTIONS https://myservice.azurewebsites.net/api/test HTTP/1.1
Accept: */*
Origin: https://myclient.azurewebsites.net
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: accept, x-my-custom-header
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net
Content-Length: 0

事前フライト要求では、HTTP OPTIONS メソッドを使用します。The pre-flight request uses the HTTP OPTIONS method. 次の2つの特殊なヘッダーが含まれます。It includes two special headers:

  • Access-Control-Request-Method: 実際の要求に使用される HTTP メソッド。Access-Control-Request-Method: The HTTP method that will be used for the actual request.
  • Access-Control-Request-Headers: アプリが実際の要求に対して設定する要求ヘッダーの一覧。Access-Control-Request-Headers: A list of request headers that the app sets on the actual request. 前述のように、これには、User-Agentなど、ブラウザーによって設定されるヘッダーは含まれません。As stated earlier, this doesn't include headers that the browser sets, such as User-Agent.

CORS のプレフライト要求には、Access-Control-Request-Headers ヘッダーが含まれる場合があります。これは、実際の要求と共に送信されるヘッダーをサーバーに示します。A CORS preflight request might include an Access-Control-Request-Headers header, which indicates to the server the headers that are sent with the actual request.

特定のヘッダーを許可するには、WithHeadersを呼び出します。To allow specific headers, call WithHeaders:

options.AddPolicy("AllowHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

すべての作成者要求ヘッダーを許可するには、AllowAnyHeaderを呼び出します。To allow all author request headers, call AllowAnyHeader:

options.AddPolicy("AllowAllHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .AllowAnyHeader();
    });

ブラウザーの Access-Control-Request-Headersの設定方法が完全に一致しているわけではありません。Browsers aren't entirely consistent in how they set Access-Control-Request-Headers. ヘッダーを "*" 以外に設定する (または AllowAnyHeaderを使用する) 場合は、少なくとも AcceptContent-Type、および Originと、サポートするカスタムヘッダーを含める必要があります。If you set headers to anything other than "*" (or use AllowAnyHeader), you should include at least Accept, Content-Type, and Origin, plus any custom headers that you want to support.

プレフライト要求に対する応答の例を次に示します (サーバーが要求を許可していることを前提としています)。The following is an example response to the preflight request (assuming that the server allows the request):

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Access-Control-Allow-Origin: https://myclient.azurewebsites.net
Access-Control-Allow-Headers: x-my-custom-header
Access-Control-Allow-Methods: PUT
Date: Wed, 20 May 2015 06:33:22 GMT

応答には、許可されたメソッドと、必要に応じて Access-Control-Allow-Headers ヘッダーを一覧表示する Access-Control-Allow-Methods ヘッダーが含まれます。これには、許可されているヘッダーが表示されます。The response includes an Access-Control-Allow-Methods header that lists the allowed methods and optionally an Access-Control-Allow-Headers header, which lists the allowed headers. プレフライト要求が成功した場合、ブラウザーは実際の要求を送信します。If the preflight request succeeds, the browser sends the actual request.

プレフライト要求が拒否された場合、アプリは200 OK応答を返しますが、CORS ヘッダーを返信しません。If the preflight request is denied, the app returns a 200 OK response but doesn't send the CORS headers back. そのため、ブラウザーはクロスオリジン要求を試行しません。Therefore, the browser doesn't attempt the cross-origin request.

プレフライトの有効期限を設定するSet the preflight expiration time

Access-Control-Max-Age ヘッダーは、プレフライト要求への応答をキャッシュできる期間を指定します。The Access-Control-Max-Age header specifies how long the response to the preflight request can be cached. このヘッダーを設定するには、SetPreflightMaxAgeを呼び出します。To set this header, call SetPreflightMaxAge:

options.AddPolicy("SetPreflightExpiration",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
    });

CORS のしくみHow CORS works

このセクションでは、HTTP メッセージレベルでのCORS要求の動作について説明します。This section describes what happens in a CORS request at the level of the HTTP messages.

  • CORS はセキュリティ機能ではありませんCORS is not a security feature. CORS は、サーバーが同じオリジンポリシーを緩めることを可能にする W3C 標準です。CORS is a W3C standard that allows a server to relax the same-origin policy.
  • CORS を許可することで、API の安全性が向上します。Your API is not safer by allowing CORS.
    • CORS を適用するには、クライアント (ブラウザー) が必要です。It's up to the client (browser) to enforce CORS. サーバーは要求を実行し、応答を返します。これは、エラーを返し、応答をブロックするクライアントです。The server executes the request and returns the response, it's the client that returns an error and blocks the response. たとえば、次のツールを使用すると、サーバーの応答が表示されます。For example, any of the following tools will display the server response:
  • これは、ブラウザーがクロスオリジンXhrまたはFetch API要求を実行して、それ以外は禁止されるようにする方法です。It's a way for a server to allow browsers to execute a cross-origin XHR or Fetch API request that otherwise would be forbidden.
    • (CORS を使用しない) ブラウザーは、クロスオリジン要求を行うことができません。Browsers (without CORS) can't do cross-origin requests. CORS の前に、この制限を回避するためにJSONPが使用されていました。Before CORS, JSONP was used to circumvent this restriction. JSONP は XHR を使用しないので、<script> タグを使用して応答を受信します。JSONP doesn't use XHR, it uses the <script> tag to receive the response. スクリプトをクロスオリジンで読み込むことができます。Scripts are allowed to be loaded cross-origin.

CORS 仕様では、クロスオリジン要求を有効にする新しい HTTP ヘッダーがいくつか導入されました。The CORS specification introduced several new HTTP headers that enable cross-origin requests. ブラウザーが CORS をサポートしている場合、クロスオリジン要求に対してこれらのヘッダーが自動的に設定されます。If a browser supports CORS, it sets these headers automatically for cross-origin requests. CORS を有効にするためにカスタム JavaScript コードは必要ありません。Custom JavaScript code isn't required to enable CORS.

次に、クロスオリジン要求の例を示します。The following is an example of a cross-origin request. Origin ヘッダーは、要求を行っているサイトのドメインを提供します。The Origin header provides the domain of the site that's making the request. Origin ヘッダーは必須であり、ホストとは異なる必要があります。The Origin header is required and must be different from the host.

GET https://myservice.azurewebsites.net/api/test HTTP/1.1
Referer: https://myclient.azurewebsites.net/
Accept: */*
Accept-Language: en-US
Origin: https://myclient.azurewebsites.net
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net

サーバーが要求を許可している場合は、応答に Access-Control-Allow-Origin ヘッダーが設定されます。If the server allows the request, it sets the Access-Control-Allow-Origin header in the response. このヘッダーの値は、要求の Origin ヘッダーと一致しているか、または "*"ワイルドカードの値であることを意味します。つまり、すべての配信元が許可されます。The value of this header either matches the Origin header from the request or is the wildcard value "*", meaning that any origin is allowed:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
Access-Control-Allow-Origin: https://myclient.azurewebsites.net
Date: Wed, 20 May 2015 06:27:30 GMT
Content-Length: 12

Test message

応答に Access-Control-Allow-Origin ヘッダーが含まれていない場合、クロスオリジン要求は失敗します。If the response doesn't include the Access-Control-Allow-Origin header, the cross-origin request fails. 具体的には、ブラウザーは要求を許可しません。Specifically, the browser disallows the request. サーバーが応答を正常に返す場合でも、ブラウザーはクライアントアプリで応答を使用できません。Even if the server returns a successful response, the browser doesn't make the response available to the client app.

CORS のテストTest CORS

CORS をテストするには:To test CORS:

  1. API プロジェクトを作成します。Create an API project. または、サンプルをダウンロードすることもできます。Alternatively, you can download the sample.
  2. このドキュメントのいずれかの方法を使用して CORS を有効にします。Enable CORS using one of the approaches in this document. 次に例を示します。For example:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    // Shows UseCors with CorsPolicyBuilder.
    app.UseCors(builder =>
    {
        builder.WithOrigins("http://example.com",
                            "http://www.contoso.com",
                            "https://localhost:44375",
                            "https://localhost:5001");
    });

    app.UseHttpsRedirection();
    app.UseMvc();
}

警告

WithOrigins("https://localhost:<port>"); は、サンプルコードのダウンロードと同様のサンプルアプリのテストにのみ使用してください。WithOrigins("https://localhost:<port>"); should only be used for testing a sample app similar to the download sample code.

  1. Web アプリプロジェクト (Razor Pages または MVC) を作成します。Create a web app project (Razor Pages or MVC). このサンプルでは、Razor Pages を使用します。The sample uses Razor Pages. API プロジェクトと同じソリューションに web アプリを作成できます。You can create the web app in the same solution as the API project.
  2. 次の強調表示されたコードをインデックスの cshtmlファイルに追加します。Add the following highlighted code to the Index.cshtml file:
@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">CORS Test</h1>
</div>

<div>
    <input type="button" value="Test" 
           onclick="requestVal('https://<web app>.azurewebsites.net/api/values')" />
    <span id='result'></span>
</div>

<script>
    function requestVal(uri) {
        const resultSpan = document.getElementById('result');

        fetch(uri)
            .then(response => response.json())
            .then(data => resultSpan.innerText = data)
            .catch(error => resultSpan.innerText = 'See F12 Console for error');
    }
</script>
  1. 上記のコードでは、url: 'https://<web app>.azurewebsites.net/api/values/1', を、デプロイされたアプリの URL に置き換えます。In the preceding code, replace url: 'https://<web app>.azurewebsites.net/api/values/1', with the URL to the deployed app.

  2. API プロジェクトをデプロイします。Deploy the API project. たとえば、 Azure にデプロイします。For example, deploy to Azure.

  3. デスクトップから Razor Pages または MVC アプリを実行し、 [テスト] ボタンをクリックします。Run the Razor Pages or MVC app from the desktop and click on the Test button. F12 ツールを使用して、エラーメッセージを確認します。Use the F12 tools to review error messages.

  4. WithOrigins から localhost の発信元を削除し、アプリをデプロイします。Remove the localhost origin from WithOrigins and deploy the app. または、別のポートを使用してクライアントアプリを実行します。Alternatively, run the client app with a different port. たとえば、Visual Studio からを実行します。For example, run from Visual Studio.

  5. クライアントアプリでテストします。Test with the client app. CORS エラーはエラーを返しますが、エラーメッセージは JavaScript では使用できません。CORS failures return an error, but the error message isn't available to JavaScript. F12 ツールの [コンソール] タブを使用して、エラーを確認します。Use the console tab in the F12 tools to see the error. ブラウザーによっては、次のようなエラー (F12 ツールコンソール) が表示されます。Depending on the browser, you get an error (in the F12 tools console) similar to the following:

    • Microsoft Edge を使用する:Using Microsoft Edge:

      SEC7120: [CORS] https://webapi.azurewebsites.net/api/values/1 のクロスオリジンリソースのアクセス制御-https://localhost:44375 応答ヘッダーに、元の https://localhost:44375 が見つかりませんでしたSEC7120: [CORS] The origin https://localhost:44375 did not find https://localhost:44375 in the Access-Control-Allow-Origin response header for cross-origin resource at https://webapi.azurewebsites.net/api/values/1

    • Chrome を使用する:Using Chrome:

      オリジン https://localhost:44375 からの https://webapi.azurewebsites.net/api/values/1 での XMLHttpRequest へのアクセスが、CORS ポリシーによってブロックされました。要求されたリソースに ' アクセス制御-発信元 ' ヘッダーは存在しません。Access to XMLHttpRequest at https://webapi.azurewebsites.net/api/values/1 from origin https://localhost:44375 has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

CORS が有効なエンドポイントは、 FiddlerPostmanなどのツールを使用してテストできます。CORS-enabled endpoints can be tested with a tool, such as Fiddler or Postman. ツールを使用する場合は、Origin ヘッダーによって指定された要求の配信元が、要求を受信しているホストと異なる必要があります。When using a tool, the origin of the request specified by the Origin header must differ from the host receiving the request. 要求が Origin ヘッダーの値に基づいてクロスオリジンでない場合は、次のようになります。If the request isn't cross-origin based on the value of the Origin header:

  • CORS ミドルウェアが要求を処理する必要はありません。There's no need for CORS Middleware to process the request.
  • CORS ヘッダーが応答で返されません。CORS headers aren't returned in the response.

IIS での CORSCORS in IIS

IIS に展開する場合、サーバーが匿名アクセスを許可するように構成されていない場合、CORS は Windows 認証の前に実行する必要があります。When deploying to IIS, CORS has to run before Windows Authentication if the server isn't configured to allow anonymous access. このシナリオをサポートするには、アプリ用にIIS CORS モジュールをインストールして構成する必要があります。To support this scenario, the IIS CORS module needs to be installed and configured for the app.

その他の技術情報Additional resources