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

作成者: Rick Anderson および Kirk LarkinBy Rick Anderson and Kirk Larkin

この記事では、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 to 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.net: 異なるドメインhttps://example.net: Different domain
  • https://www.example.com/foo.html: 異なるサブドメインhttps://www.example.com/foo.html: Different subdomain
  • http://example.com/foo.html: 異なるスキームhttp://example.com/foo.html: Different scheme
  • https://example.com:9000/foo.html: 別のポートhttps://example.com:9000/foo.html: Different port

CORS を有効にするEnable CORS

CORS を有効にするには、次の3つの方法があります。There are three ways to enable CORS:

名前付きポリシーで [Enablecors] 属性を使用すると、CORS をサポートするエンドポイントを制限するための最も細かい制御が可能になります。Using the [EnableCors] attribute with a named policy provides the finest control in limiting endpoints that support CORS.

警告

UseCors を使用する場合は、前にを呼び出す必要があり UseResponseCaching UseResponseCaching ます。UseCors must be called before UseResponseCaching when using UseResponseCaching.

各方法の詳細については、次のセクションで説明します。Each approach is detailed in the following sections.

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

CORS ミドルウェアは、クロスオリジン要求を処理します。CORS Middleware handles cross-origin requests. 次のコードは、指定されたオリジンを持つすべてのアプリのエンドポイントに CORS ポリシーを適用します。The following code applies a CORS policy to all the app's endpoints with the specified origins:

public class Startup
{
    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

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

        // services.AddResponseCaching();
        services.AddControllers();
    }

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors(MyAllowSpecificOrigins);

        // app.UseResponseCaching();

        app.UseAuthorization();

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

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

  • ポリシー名をに設定 _myAllowSpecificOrigins します。Sets the policy name to _myAllowSpecificOrigins. ポリシー名は任意です。The policy name is arbitrary.
  • 拡張メソッドを呼び出し、 UseCors CORS ポリシーを指定し _myAllowSpecificOrigins ます。Calls the UseCors extension method and specifies the _myAllowSpecificOrigins CORS policy. UseCors CORS ミドルウェアを追加します。UseCors adds the CORS middleware. への呼び出しは UseCors UseRouting 、の後、の前に配置する必要があり UseAuthorization ます。The call to UseCors must be placed after UseRouting, but before UseAuthorization. 詳細については、「 ミドルウェアの順序」を参照してください。For more information, see Middleware order.
  • 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.
  • _myAllowSpecificOriginsすべてのコントローラーエンドポイントに対して CORS ポリシーを有効にします。Enables the _myAllowSpecificOrigins CORS policy for all controller endpoints. 特定のエンドポイントに CORS ポリシーを適用するには、「 エンドポイントルーティング 」を参照してください。See endpoint routing to apply a CORS policy to specific endpoints.
  • 応答キャッシュミドルウェアを使用する場合は、の UseCors 前にを呼び出し UseResponseCaching ます。When using Response Caching Middleware, call UseCors before UseResponseCaching.

エンドポイントルーティングでは、CORS ミドルウェアをとの呼び出しの間で実行するように構成する 必要があり UseRouting UseEndpoints ます。With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints.

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

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

public class Startup
{
    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

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

        // services.AddResponseCaching();
        services.AddControllers();
    }

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

メソッドは、 CorsPolicyBuilder 次のコードに示すように、連結できます。The CorsPolicyBuilder methods can be chained, 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.AddControllers();
}

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

既定のポリシーとミドルウェアを使用した CORSCORS with default policy and middleware

次の強調表示されたコードは、既定の CORS ポリシーを有効にします。The following highlighted code enables the default CORS policy:

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

        services.AddControllers();
    }

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

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

上記のコードは、すべてのコントローラーエンドポイントに既定の CORS ポリシーを適用します。The preceding code applies the default CORS policy to all controller endpoints.

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

現在、を使用して、エンドポイントごとに CORS を有効にする RequireCors ことは、 自動プレフライト要求をサポートして いませんEnabling CORS on a per-endpoint basis using RequireCors currently does not support automatic preflight requests. 詳細については、こちらの GitHub の問題 を参照してください。また、 エンドポイントルーティングと [HttpOptions] を使用して CORS をテストしてください。For more information, see this GitHub issue and Test CORS with endpoint routing and [HttpOptions].

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

public class Startup
{
    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

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

        services.AddControllers();
        services.AddRazorPages();
    }

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/echo",
                context => context.Response.WriteAsync("echo"))
                .RequireCors(MyAllowSpecificOrigins);

            endpoints.MapControllers()
                     .RequireCors(MyAllowSpecificOrigins);

            endpoints.MapGet("/echo2",
                context => context.Response.WriteAsync("echo2"));

            endpoints.MapRazorPages();
        });
    }
}

上記のコードにより、次のことが行われます。In the preceding code:

  • app.UseCors CORS ミドルウェアを有効にします。app.UseCors enables the CORS middleware. 既定のポリシーが構成されていないため、 app.UseCors() 単独で CORS を有効にすることはできません。Because a default policy hasn't been configured, app.UseCors() alone doesn't enable CORS.
  • /echoおよびコントローラーエンドポイントは、指定されたポリシーを使用して、クロスオリジン要求を許可します。The /echo and controller endpoints allow cross-origin requests using the specified policy.
  • /echo2既定のポリシーが指定されていないため、と Razor Pages エンドポイントはクロスオリジン要求を許可し ませんThe /echo2 and Razor Pages endpoints do not allow cross-origin requests because no default policy was specified.

[Disablecors]属性では、を使用してエンドポイントルーティングによって有効にされた CORS は無効になり ません RequireCorsThe [DisableCors] attribute does not disable CORS that has been enabled by endpoint routing with RequireCors.

前述のようなコードをテストする方法については、「 エンドポイントルーティングを使用した CORS のテスト」および「[HttpOptions] 」を参照してください。See Test CORS with endpoint routing and [HttpOptions] for instructions on testing code similar to the preceding.

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

[Enablecors]属性を使用して cors を有効にし、cors を必要とするエンドポイントのみに名前付きポリシーを適用することで、最も細かい制御が可能になります。Enabling CORS with the [EnableCors] attribute and applying a named policy to only those endpoints that require CORS provides the finest control.

[Enablecors]属性は、CORS をグローバルに適用するための代替手段を提供します。The [EnableCors] attribute provides an alternative to applying CORS globally. 属性は、 [EnableCors] すべてのエンドポイントではなく、選択したエンドポイントに対して CORS を有効にします。The [EnableCors] attribute enables CORS for selected endpoints, rather than all endpoints:

  • [EnableCors] 既定のポリシーを指定します。[EnableCors] specifies the default policy.
  • [EnableCors("{Policy String}")] 名前付きポリシーを指定します。[EnableCors("{Policy String}")] specifies a named policy.

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

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

属性を使用して、さまざまなポリシーをコントローラー、ページモデル、またはアクションメソッドに適用でき [EnableCors] ます。Different policies can be applied to controllers, page models, or action methods with the [EnableCors] attribute. [EnableCors]属性がコントローラー、ページモデル、またはアクションメソッドに適用され、CORS がミドルウェアで有効になっている場合、 両方 のポリシーが適用されます。When the [EnableCors] attribute is applied to a controller, page model, or action method, and CORS is enabled in middleware, both policies are applied. ポリシーを組み合わせることはお勧めしません。 [EnableCors] 同じアプリ内ではなく、属性またはミドルウェアを使用します。We recommend against combining policies. 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("Policy1")]
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        return id switch
        {
            1 => "green widget",
            2 => "red widget",
            _ => NotFound(),
        };
    }
}

次のコードでは、2つの CORS ポリシーを作成します。The following code creates two CORS policies:

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

    public IConfiguration Configuration { get; }

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

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

        services.AddControllers();
    }

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

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

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

CORS 要求を制限する最も細かい制御:For the finest control of limiting CORS requests:

  • [EnableCors("MyPolicy")]名前付きポリシーでを使用します。Use [EnableCors("MyPolicy")] with a named policy.
  • 既定のポリシーは定義しないでください。Don't define a default policy.
  • エンドポイントルーティングを使用しないでください。Don't use endpoint routing.

次のセクションのコードは、上記のリストを満たしています。The code in the next section meets the preceding list.

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

CORS を無効にするDisable CORS

[Disablecors]属性は、 エンドポイントルーティングによって有効にされた CORS を無効にし ませんThe [DisableCors] attribute does not disable CORS that has been enabled by endpoint routing.

次のコードでは、CORS ポリシーを定義してい "MyPolicy" ます。The following code defines the CORS policy "MyPolicy":

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: "MyPolicy",
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com")
                            .WithMethods("PUT", "DELETE", "GET");
                });
        });

        services.AddControllers();
        services.AddRazorPages();
    }

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

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

次のコードは、アクションの CORS を無効にし GetValues2 ます。The following code disables CORS for the GetValues2 action:

[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public IActionResult Get() =>
        ControllerContext.MyDisplayRouteInfo();

    // GET api/values/5
    [HttpGet("{id}")]
    public IActionResult Get(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // PUT api/values/5
    [HttpPut("{id}")]
    public IActionResult Put(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);


    // GET: api/values/GetValues2
    [DisableCors]
    [HttpGet("{action}")]
    public IActionResult GetValues2() =>
        ControllerContext.MyDisplayRouteInfo();

}

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

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

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

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

AddPolicy はで呼び出され Startup.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: 任意のスキーム (または) を持つすべてのオリジンからの CORS 要求を許可 http https します。AllowAnyOrigin: Allows CORS requests from all origins with any scheme (http or https). AllowAnyOriginweb サイト はアプリに対してクロスオリジン要求を行うことができるため、安全ではありません。AllowAnyOrigin is insecure because any website can make cross-origin requests to the app.

注意

とを指定すると、 AllowAnyOrigin AllowCredentials 安全ではない構成で、クロスサイト要求の偽造が発生する可能性があります。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.

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("MyAllowSubdomainPolicy",
    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("MyAllowHeadersPolicy",
    builder =>
    {
        // requires using Microsoft.Net.Http.Headers;
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

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

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

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

によって指定された特定のヘッダーに対して CORS ミドルウェアポリシーが一致するのは、ヘッダーがで記述されているヘッダーと WithHeaders 完全に一致する場合のみです Access-Control-Request-Headers WithHeadersA 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));

CORS ミドルウェアは、次の要求ヘッダーを使用してプレフライト要求を拒否し Content-Language ます。 (headernames) は、には記載されていないため WithHeaders です。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.

公開された応答ヘッダーを設定する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("MyExposeResponseHeadersPolicy",
    builder =>
    {
        builder.WithOrigins("https://*.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.withCredentials true ます。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("MyMyAllowCredentialsPolicy",
    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 OPTIONS request before making the actual request. この要求は プレフライト要求と呼ばれます。This request is called a preflight request. 次の すべて の条件に該当する場合、ブラウザーはプレフライト要求をスキップできます。The browser can skip the preflight request if all the following conditions are true:

  • 要求メソッドは GET、HEAD、または POST です。The request method is GET, HEAD, or POST.
  • アプリで Accept は、、、 Accept-Language Content-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

クライアント要求に対して設定された要求ヘッダーに適用される規則は、オブジェクトに対してを呼び出すことによって、アプリが設定するヘッダーに適用され setRequestHeader XMLHttpRequest ます。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-Agent Host Content-LengthThe rule doesn't apply to headers the browser can set, such as User-Agent, Host, or Content-Length.

次に示すのは、このドキュメントの「 テスト CORS 」セクションの [Put test] ボタンから行ったプレフライト要求に似た応答の例です。The following is an example response similar to the preflight request made from the [Put test] button in the Test CORS section of this document.

General:
Request URL: https://cors3.azurewebsites.net/api/values/5
Request Method: OPTIONS
Status Code: 204 No Content

Response Headers:
Access-Control-Allow-Methods: PUT,DELETE,GET
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f8...8;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Vary: Origin

Request Headers:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Method: PUT
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0

プレフライト要求では、 HTTP OPTIONS メソッドを使用します。The preflight request uses the HTTP OPTIONS method. 次のヘッダーが含まれている場合があります。It may include the following headers:

プレフライト要求が拒否された場合、アプリは応答を返し 200 OK ますが、CORS ヘッダーは設定しません。If the preflight request is denied, the app returns a 200 OK response but doesn't set the CORS headers. そのため、ブラウザーはクロスオリジン要求を試行しません。Therefore, the browser doesn't attempt the cross-origin request. 拒否されたプレフライト要求の例については、このドキュメントの「 テスト CORS 」セクションを参照してください。For an example of a denied preflight request, see the Test CORS section of this document.

F12 ツールを使用すると、コンソールアプリには、ブラウザーに応じて次のいずれかのようなエラーが表示されます。Using the F12 tools, the console app shows an error similar to one of the following, depending on the browser:

  • Firefox: クロスオリジン要求がブロックされています: 同じオリジンポリシーで、でのリモートリソースの読み取りが許可されて https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 いません。Firefox: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5. (理由: CORS 要求が失敗しました)。(Reason: CORS request did not succeed). 詳細情報Learn More
  • Chromium ベース: オリジン ' ' からの ' ' でのフェッチへのアクセス https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5 https://cors3.azurewebsites.net が CORS ポリシーによってブロックされました。プレフライト要求への応答がアクセス制御チェックに合格しません: 要求されたリソースに ' アクセス制御-許可-オリジン ' ヘッダーが存在しません。Chromium based: Access to fetch at 'https://cors1.azurewebsites.net/api/TodoItems1/MyDelete2/5' from origin 'https://cors3.azurewebsites.net' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 非透過の応答が要求に対応している場合は、要求のモードを 'no-cors' に設定し、CORS を無効にしてリソースをフェッチしてください。If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

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

options.AddPolicy("MyAllowHeadersPolicy",
    builder =>
    {
        // requires using Microsoft.Net.Http.Headers;
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

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

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

ブラウザーの設定方法が一貫していません Access-Control-Request-HeadersBrowsers aren't consistent in how they set Access-Control-Request-Headers. 次のいずれかの場合:If either:

  • ヘッダーは、 "*"Headers are set to anything other than "*"
  • AllowAnyHeader が呼び出されます: 少なくとも、、、 Accept Content-Type Origin 、およびサポートするカスタムヘッダーを含めます。AllowAnyHeader is called: Include at least Accept, Content-Type, and Origin, plus any custom headers that you want to support.

自動プレフライト要求コードAutomatic preflight request code

CORS ポリシーを適用する場合は、次のいずれかの方法を実行します。When the CORS policy is applied either:

  • でを呼び出すことにより、グローバルに app.UseCors Startup.ConfigureGlobally by calling app.UseCors in Startup.Configure.
  • 属性を使用し [EnableCors] ます。Using the [EnableCors] attribute.

ASP.NET Core は、プレフライトオプション要求に応答します。ASP.NET Core responds to the preflight OPTIONS request.

現在、を使用して、エンドポイントごとに CORS を有効にする RequireCors ことは、自動プレフライト要求をサポートして いませんEnabling CORS on a per-endpoint basis using RequireCors currently does not support automatic preflight requests.

このドキュメントの「 テスト CORS 」セクションでは、この動作について説明します。The Test CORS section of this document demonstrates this behavior.

プレフライト要求の [HttpOptions] 属性[HttpOptions] attribute for preflight requests

CORS が適切なポリシーで有効になっている場合、ASP.NET Core は通常、CORS プレフライト要求に自動的に応答します。When CORS is enabled with the appropriate policy, ASP.NET Core generally responds to CORS preflight requests automatically. シナリオによっては、これが当てはまりません。In some scenarios, this may not be the case. たとえば、CORS を エンドポイントルーティングと共に使用します。For example, using CORS with endpoint routing.

次のコードでは、 [HttpOptions] 属性を使用して、OPTIONS 要求のエンドポイントを作成します。The following code uses the [HttpOptions] attribute to create endpoints for OPTIONS requests:

[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
    // OPTIONS: api/TodoItems2/5
    [HttpOptions("{id}")]
    public IActionResult PreflightRoute(int id)
    {
        return NoContent();
    }

    // OPTIONS: api/TodoItems2 
    [HttpOptions]
    public IActionResult PreflightRoute()
    {
        return NoContent();
    }

    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return BadRequest();
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

前のコードをテストする手順については、「 エンドポイントルーティングを使用した CORS のテスト」および「[HttpOptions] 」を参照してください。See Test CORS with endpoint routing and [HttpOptions] for instructions on testing the preceding code.

プレフライトの有効期限を設定する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("MySetPreflightExpirationPolicy",
    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.
    • たとえば、悪意のあるアクターがサイトに対して クロスサイトスクリプティング (XSS) を使用して、CORS が有効になっているサイトに対してクロスサイト要求を実行し、情報を盗むことができます。For example, a malicious actor could use Cross-Site Scripting (XSS) against your site and execute a cross-site request to their CORS enabled site to steal information.
  • CORS を許可することで、API の安全性が向上します。An API isn't 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 PUT test button on the deployed sample

次に、[ のテスト] ボタンからへのクロスオリジン要求の例を示し https://cors1.azurewebsites.net/api/values ます。The following is an example of a cross-origin request from the Values test button to https://cors1.azurewebsites.net/api/values. Originヘッダー:The Origin header:

  • 要求を行っているサイトのドメインを提供します。Provides the domain of the site that's making the request.
  • は必須であり、ホストと異なる必要があります。Is required and must be different from the host.

一般的なヘッダーGeneral headers

Request URL: https://cors1.azurewebsites.net/api/values
Request Method: GET
Status Code: 200 OK

応答ヘッダーResponse headers

Content-Encoding: gzip
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors1.azurewebsites.net
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Powered-By: ASP.NET

要求ヘッダーRequest headers

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: cors1.azurewebsites.net
Origin: https://cors3.azurewebsites.net
Referer: https://cors3.azurewebsites.net/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 ...

要求では、 OPTIONS サーバーは応答 Response headers のヘッダーヘッダーを設定し Access-Control-Allow-Origin: {allowed origin} ます。In OPTIONS requests, the server sets the Response headers Access-Control-Allow-Origin: {allowed origin} header in the response. たとえば、デプロイされた サンプルDelete [enablecors] button 要求には、 OPTIONS 次のヘッダーが含まれています。For example, the deployed sample, Delete [EnableCors] button OPTIONS request contains the following headers:

一般的なヘッダーGeneral headers

Request URL: https://cors3.azurewebsites.net/api/TodoItems2/MyDelete2/5
Request Method: OPTIONS
Status Code: 204 No Content

応答ヘッダーResponse headers

Access-Control-Allow-Headers: Content-Type,x-custom-header
Access-Control-Allow-Methods: PUT,DELETE,GET,OPTIONS
Access-Control-Allow-Origin: https://cors1.azurewebsites.net
Server: Microsoft-IIS/10.0
Set-Cookie: ARRAffinity=8f...;Path=/;HttpOnly;Domain=cors3.azurewebsites.net
Vary: Origin
X-Powered-By: ASP.NET

要求ヘッダーRequest headers

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: DELETE
Connection: keep-alive
Host: cors3.azurewebsites.net
Origin: https://cors1.azurewebsites.net
Referer: https://cors1.azurewebsites.net/test?number=2
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0

上記の 応答ヘッダー では、サーバーは応答で アクセス制御-許可 ヘッダーを設定します。In the preceding Response headers , the server sets the Access-Control-Allow-Origin header in the response. https://cors1.azurewebsites.netこのヘッダーの値は、要求のヘッダーと一致し Origin ます。The https://cors1.azurewebsites.net value of this header matches the Origin header from the request.

AllowAnyOriginが呼び出されると、 Access-Control-Allow-Origin: * ワイルドカード値が返されます。If AllowAnyOrigin is called, the Access-Control-Allow-Origin: *, the wildcard value, is returned. AllowAnyOrigin 任意の発信元を許可します。AllowAnyOrigin allows any origin.

応答にヘッダーが含まれていない場合 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.

表示オプションの要求Display OPTIONS requests

既定では、Chrome および Edge ブラウザーでは、F12 ツールの [ネットワーク] タブの [要求] オプションが表示されません。By default, the Chrome and Edge browsers don't show OPTIONS requests on the network tab of the F12 tools. これらのブラウザーでオプションの要求を表示するには:To display OPTIONS requests in these browsers:

  • chrome://flags/#out-of-blink-cors または edge://flags/#out-of-blink-corschrome://flags/#out-of-blink-cors or edge://flags/#out-of-blink-cors
  • フラグを無効にします。disable the flag.
  • [再起動] をタップします。restart.

既定では、Firefox によってオプションの要求が表示されます。Firefox shows OPTIONS requests by default.

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.

CORS のテストTest CORS

サンプルダウンロードには、CORS をテストするコードが含まれています。The sample download has code to test CORS. ダウンロード方法に関するページを参照してください。See how to download. このサンプルは、ページが追加された API プロジェクトです Razor 。The sample is an API project with Razor Pages added:

public class StartupTest2
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: "MyPolicy",
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                        "http://www.contoso.com",
                        "https://cors1.azurewebsites.net",
                        "https://cors3.azurewebsites.net",
                        "https://localhost:44398",
                        "https://localhost:5001")
                            .WithMethods("PUT", "DELETE", "GET");
                });
        });

        services.AddControllers();
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

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

警告

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

ValuesControllerテスト用のエンドポイントは次のとおりです。The following ValuesController provides the endpoints for testing:

[EnableCors("MyPolicy")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public IActionResult Get() =>
        ControllerContext.MyDisplayRouteInfo();

    // GET api/values/5
    [HttpGet("{id}")]
    public IActionResult Get(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // PUT api/values/5
    [HttpPut("{id}")]
    public IActionResult Put(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);


    // GET: api/values/GetValues2
    [DisableCors]
    [HttpGet("{action}")]
    public IActionResult GetValues2() =>
        ControllerContext.MyDisplayRouteInfo();

}

Mydisplayrouteinfo は、Rick.Doc. routeinfo NuGet パッケージによって提供され、ルート情報を表示します。MyDisplayRouteInfo is provided by the Rick.Docs.Samples.RouteInfo NuGet package and displays route information.

次のいずれかの方法を使用して、上記のサンプルコードをテストします。Test the preceding sample code by using one of the following approaches:

  • でデプロイされたサンプルアプリを使用し https://cors3.azurewebsites.net/ ます。Use the deployed sample app at https://cors3.azurewebsites.net/. サンプルをダウンロードする必要はありません。There is no need to download the sample.
  • dotnet runの既定の URL を使用して、サンプルを実行し https://localhost:5001 ます。Run the sample with dotnet run using the default URL of https://localhost:5001.
  • URL に対してポートを44398に設定して、Visual Studio からサンプルを実行し https://localhost:44398 ます。Run the sample from Visual Studio with the port set to 44398 for a URL of https://localhost:44398.

F12 ツールでブラウザーを使用すると、次のようになります。Using a browser with the F12 tools:

  • [ ] をクリックし、[ ネットワーク ] タブでヘッダーを確認します。Select the Values button and review the headers in the Network tab.

  • [ テストの配置 ] ボタンを選択します。Select the PUT test button. OPTIONS 要求を表示する方法については、「 表示オプションの要求 」を参照してください。See Display OPTIONS requests for instructions on displaying the OPTIONS request. Put テスト では、2つの要求、オプションのプレフライト要求、および put 要求が作成されます。The PUT test creates two requests, an OPTIONS preflight request and the PUT request.

  • 失敗し GetValues2 [DisableCors] た CORS 要求をトリガーするには、このボタンを選択します。Select the GetValues2 [DisableCors] button to trigger a failed CORS request. ドキュメントに記載されているように、応答は200成功を返しますが、CORS 要求は行われません。As mentioned in the document, the response returns 200 success, but the CORS request is not made. [ コンソール ] タブを選択して、CORS エラーを確認します。Select the Console tab to see the CORS error. ブラウザーによっては、次のようなエラーが表示されます。Depending on the browser, an error similar to the following is displayed:

    'https://cors1.azurewebsites.net/api/values/GetValues2'送信元からのフェッチへのアクセス 'https://cors3.azurewebsites.net' が CORS ポリシーによってブロックされました。要求されたリソースに ' アクセス制御許可-発信元 ' ヘッダーが存在しません。Access to fetch at 'https://cors1.azurewebsites.net/api/values/GetValues2' from origin 'https://cors3.azurewebsites.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 非透過の応答が要求に対応している場合は、要求のモードを 'no-cors' に設定し、CORS を無効にしてリソースをフェッチしてください。If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

CORS が有効なエンドポイントは、 curlFiddlerPostmanなどのツールを使用してテストできます。CORS-enabled endpoints can be tested with a tool, such as curl, 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.

次のコマンドは、を使用し curl て、情報を含む OPTIONS 要求を発行します。The following command uses curl to issue an OPTIONS request with information:

curl -X OPTIONS https://cors3.azurewebsites.net/api/TodoItems2/5 -i

エンドポイントルーティングを使用した CORS のテスト [HttpOptions]Test CORS with endpoint routing and [HttpOptions]

現在、を使用して、エンドポイントごとに CORS を有効にする RequireCors ことは、 自動プレフライト要求をサポートして いませんEnabling CORS on a per-endpoint basis using RequireCors currently does not support automatic preflight requests. エンドポイントルーティングを使用して CORS を有効にする次のコードについて考えてみます。Consider the following code which uses endpoint routing to enable CORS:

public class StartupEndPointBugTest
{
    readonly string MyPolicy = "_myPolicy";

    // .WithHeaders(HeaderNames.ContentType, "x-custom-header")
    // forces browsers to require a preflight request with GET

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: MyPolicy,
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com",
                                        "https://cors1.azurewebsites.net",
                                        "https://cors3.azurewebsites.net",
                                        "https://localhost:44398",
                                        "https://localhost:5001")
                           .WithHeaders(HeaderNames.ContentType, "x-custom-header")
                           .WithMethods("PUT", "DELETE", "GET", "OPTIONS");
                });
        });

        services.AddControllers();
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

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

TodoItems1Controllerテスト用のエンドポイントは次のとおりです。The following TodoItems1Controller provides endpoints for testing:

[Route("api/[controller]")]
[ApiController]
public class TodoItems1Controller : ControllerBase
{
    // PUT: api/TodoItems1/5
    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return Content($"ID = {id}");
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

    // Delete: api/TodoItems1/5
    [HttpDelete("{id}")]
    public IActionResult MyDelete(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    // GET: api/TodoItems1
    [HttpGet]
    public IActionResult GetTodoItems() =>
        ControllerContext.MyDisplayRouteInfo();

    [EnableCors]
    [HttpGet("{action}")]
    public IActionResult GetTodoItems2() =>
        ControllerContext.MyDisplayRouteInfo();

    // Delete: api/TodoItems1/MyDelete2/5
    [EnableCors]
    [HttpDelete("{action}/{id}")]
    public IActionResult MyDelete2(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);
}

配置されたサンプルテストページから、前のコードをテストします。Test the preceding code from the test page of the deployed sample.

エンドポイントがプレフライト要求に応答して応答するため、 Delete [EnableCors ] ボタンは 正常に終了し [EnableCors] ます。The Delete [EnableCors] and GET [EnableCors] buttons succeed, because the endpoints have [EnableCors] and respond to preflight requests. 他のエンドポイントは失敗します。The other endpoints fails. JavaScriptによってが送信されるため、 GET ボタンは失敗します。The GET button fails, because the JavaScript sends:

 headers: {
      "Content-Type": "x-custom-header"
 },

次の例は TodoItems2Controller 同様のエンドポイントを提供しますが、オプションの要求に応答するための明示的なコードが含まれています。The following TodoItems2Controller provides similar endpoints, but includes explicit code to respond to OPTIONS requests:

[Route("api/[controller]")]
[ApiController]
public class TodoItems2Controller : ControllerBase
{
    // OPTIONS: api/TodoItems2/5
    [HttpOptions("{id}")]
    public IActionResult PreflightRoute(int id)
    {
        return NoContent();
    }

    // OPTIONS: api/TodoItems2 
    [HttpOptions]
    public IActionResult PreflightRoute()
    {
        return NoContent();
    }

    [HttpPut("{id}")]
    public IActionResult PutTodoItem(int id)
    {
        if (id < 1)
        {
            return BadRequest();
        }

        return ControllerContext.MyDisplayRouteInfo(id);
    }

    // [EnableCors] // Not needed as OPTIONS path provided
    [HttpDelete("{id}")]
    public IActionResult MyDelete(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);

    [EnableCors]  // Rquired for this path
    [HttpGet]
    public IActionResult GetTodoItems() =>
        ControllerContext.MyDisplayRouteInfo();

    [HttpGet("{action}")]
    public IActionResult GetTodoItems2() =>
        ControllerContext.MyDisplayRouteInfo();

    [EnableCors]  // Rquired for this path
    [HttpDelete("{action}/{id}")]
    public IActionResult MyDelete2(int id) =>
        ControllerContext.MyDisplayRouteInfo(id);
}

配置されたサンプルの テストページ から、前のコードをテストします。Test the preceding code from the test page of the deployed sample. [ コントローラー ] ドロップダウンリストで、[ プレフライト ] を選択し、[ コントローラーの設定 ] をクリックします。In the Controller drop down list, select Preflight and then Set Controller . エンドポイントに対するすべての CORS 呼び出しが TodoItems2Controller 成功します。All the CORS calls to the TodoItems2Controller endpoints succeed.

その他の資料Additional resources

作成者: 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.net: 異なるドメインhttps://example.net: Different domain
  • https://www.example.com/foo.html: 異なるサブドメインhttps://www.example.com/foo.html: Different subdomain
  • http://example.com/foo.html: 異なるスキームhttp://example.com/foo.html: Different scheme
  • https://example.com:9000/foo.html: 別のポートhttps://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.
  • UseCorsCORS を有効にする拡張メソッドを呼び出します。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 ミドルウェアを使用してすべてのアプリのエンドポイントに 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();
}

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

ページ/コントローラー/アクションレベルで CORS ポリシーを適用するには Razor 、「ページ、コントローラー、およびアクションメソッドで 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 code similar to the preceding code.

属性を使用して 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 not combining policies. [EnableCors]両方では なく 、属性またはミドルウェアを使用します。Use the [EnableCors] attribute or middleware, not both . を使用する場合は [EnableCors] 、既定のポリシーを定義 しないで ください。When using [EnableCors], do not define a default policy.

次のコードは、各メソッドに異なるポリシーを適用します。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:

AddPolicy はで呼び出され Startup.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: 任意のスキーム (または) を持つすべてのオリジンからの CORS 要求を許可 http https します。AllowAnyOrigin: Allows CORS requests from all origins with any scheme (http or https). AllowAnyOriginweb サイト はアプリに対してクロスオリジン要求を行うことができるため、安全ではありません。AllowAnyOrigin is insecure because any website can make cross-origin requests to the app.

注意

とを指定すると、 AllowAnyOrigin AllowCredentials 安全ではない構成で、クロスサイト要求の偽造が発生する可能性があります。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.

CORS ミドルウェアでは、 Access-Control-Request-Headers CorsPolicy で構成されている値に関係なく、常にの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));

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

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.withCredentials true ます。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.
  • アプリで Accept は、、、 Accept-Language Content-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

クライアント要求に対して設定された要求ヘッダーに適用される規則は、オブジェクトに対してを呼び出すことによって、アプリが設定するヘッダーに適用され setRequestHeader XMLHttpRequest ます。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-Agent Host Content-LengthThe 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-AgentAs stated earlier, this doesn't include headers that the browser sets, such as User-Agent.

CORS が適切なポリシーで有効になっている場合、ASP.NET Core は通常、CORS プレフライト要求に自動的に応答します。When CORS is enabled with the appropriate policy, ASP.NET Core generally automatically responds to CORS preflight requests. プレフライト要求の場合は、[HttpOptions] 属性を参照してください。See [HttpOptions] attribute for preflight requests.

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-HeadersBrowsers aren't entirely consistent in how they set Access-Control-Request-Headers. ヘッダーを以外の任意の値 (またはを使用) に設定する場合は、少なくとも、、、 "*" AllowAnyHeader Accept Content-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-Methods 許可されているメソッドと、必要に応じてヘッダーを一覧表示するヘッダーが含まれてい Access-Control-Allow-Headers ます。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 します (ページまたは MVC)。Create a web app project (Razor Pages or MVC). このサンプルでは、 Razor ページを使用します。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デスクトップからページまたは 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. から localhost の配信元を削除 WithOrigins し、アプリをデプロイします。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://localhost:44375 https://localhost:44375 場所にあるクロスオリジンリソースのアクセス制御-許可-オリジン応答ヘッダーで見つかりませんでした https://webapi.azurewebsites.net/api/values/1SEC7120: [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://webapi.azurewebsites.net/api/values/1オリジンからの XMLHttpRequest へのアクセス https://localhost:44375 が 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