Habilitar as solicitações entre origens (CORS) no ASP.NET CoreEnable Cross-Origin Requests (CORS) in ASP.NET Core

Por Rick AndersonBy Rick Anderson

Este artigo mostra como habilitar o CORS em um aplicativo ASP.NET Core.This article shows how to enable CORS in an ASP.NET Core app.

A segurança do navegador impede que uma página da Web faça solicitações para um domínio diferente daquele que servia a página da Web.Browser security prevents a web page from making requests to a different domain than the one that served the web page. Essa restrição é chamada de política de mesma origem.This restriction is called the same-origin policy. A política de mesma origem impede que um site mal-intencionado leia dados confidenciais de outro site.The same-origin policy prevents a malicious site from reading sensitive data from another site. Às vezes, talvez você queira permitir que outros sites façam solicitações entre origens para seu aplicativo.Sometimes, you might want to allow other sites make cross-origin requests to your app. Para obter mais informações, consulte o artigo de CORS do Mozilla.For more information, see the Mozilla CORS article.

CORS ( compartilhamento de recursos entre origens ):Cross Origin Resource Sharing (CORS):

  • É um padrão W3C que permite que um servidor Relaxe a política de mesma origem.Is a W3C standard that allows a server to relax the same-origin policy.
  • Não é um recurso de segurança, o CORS libera a segurança.Is not a security feature, CORS relaxes security. Uma API não é mais segura, permitindo CORS.An API is not safer by allowing CORS. Para obter mais informações, consulte como o CORS funciona.For more information, see How CORS works.
  • Permite que um servidor permita explicitamente algumas solicitações entre origens enquanto rejeita outras.Allows a server to explicitly allow some cross-origin requests while rejecting others.
  • É mais seguro e flexível do que as técnicas anteriores, como JSONP.Is safer and more flexible than earlier techniques, such as JSONP.

Exibir ou baixar código de exemplo (como baixar)View or download sample code (how to download)

Mesma origemSame origin

Duas URLs têm a mesma origem se tiverem esquemas, hosts e portas idênticos (RFC 6454).Two URLs have the same origin if they have identical schemes, hosts, and ports (RFC 6454).

Essas duas URLs têm a mesma origem:These two URLs have the same origin:

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

Essas URLs têm origens diferentes das duas URLs anteriores:These URLs have different origins than the previous two URLs:

  • https://example.net – domínio diferentehttps://example.net – Different domain
  • https://www.example.com/foo.html – subdomínio diferentehttps://www.example.com/foo.html – Different subdomain
  • http://example.com/foo.html – esquema diferentehttp://example.com/foo.html – Different scheme
  • https://example.com:9000/foo.html – porta diferentehttps://example.com:9000/foo.html – Different port

O Internet Explorer não considera a porta ao comparar origens.Internet Explorer doesn't consider the port when comparing origins.

CORS com política nomeada e middlewareCORS with named policy and middleware

O middleware CORS lida com solicitações entre origens.CORS Middleware handles cross-origin requests. O código a seguir habilita o CORS para todo o aplicativo com a origem especificada: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();
    }
}

O código anterior:The preceding code:

A chamada de método AddCors adiciona serviços CORS ao contêiner de serviço do aplicativo: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);
}

Para obter mais informações, consulte Opções de política de CORS neste documento.For more information, see CORS policy options in this document .

O método CorsPolicyBuilder pode encadear métodos, conforme mostrado no código a seguir: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);
}

Observação: a URL não deve conter uma barra à direita (/).Note: The URL must not contain a trailing slash (/). Se a URL for encerrada com /, a comparação retornará false e nenhum cabeçalho será retornado.If the URL terminates with /, the comparison returns false and no header is returned.

Aplicar políticas CORS a todos os pontos de extremidadeApply CORS policies to all endpoints

O código a seguir aplica políticas CORS a todos os pontos de extremidade de aplicativos por meio do middleware 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.
}

Aviso

Com o roteamento de ponto de extremidade, o middleware CORS deve ser configurado para ser executado entre as chamadas para UseRouting e UseEndpoints.With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints. A configuração incorreta fará com que o middleware pare de funcionar corretamente.Incorrect configuration will cause the middleware to stop functioning correctly.

O código a seguir aplica políticas CORS a todos os pontos de extremidade de aplicativos por meio do middleware 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();
}

Observação: UseCors deve ser chamado antes de UseMvc.Note: UseCors must be called before UseMvc.

Consulte habilitar CORS em Razor pages, controladores e métodos de ação para aplicar a política CORS no nível de página/controlador/ação.See Enable CORS in Razor Pages, controllers, and action methods to apply CORS policy at the page/controller/action level.

Consulte testar CORS para obter instruções sobre como testar o código anterior.See Test CORS for instructions on testing the preceding code.

Habilitar CORS com roteamento de ponto de extremidadeEnable Cors with endpoint routing

Com o roteamento de ponto de extremidade, o CORS pode ser habilitado em uma base por ponto de extremidade usando o conjunto RequireCors de métodos de extensão.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");
});

Da mesma forma, o CORS também pode ser habilitado para todos os controladores:Similarly, CORS can also be enabled for all controllers:

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

Habilitar CORS com atributosEnable CORS with attributes

O atributo [EnableCors @ no__t-2 fornece uma alternativa para aplicar o CORS globalmente.The [EnableCors] attribute provides an alternative to applying CORS globally. O atributo [EnableCors] habilita o CORS para os pontos de extremidade selecionados, em vez de todos os pontos de extremidade.The [EnableCors] attribute enables CORS for selected end points, rather than all end points.

Use [EnableCors] para especificar a política padrão e [EnableCors("{Policy String}")] para especificar uma política.Use [EnableCors] to specify the default policy and [EnableCors("{Policy String}")] to specify a policy.

O atributo [EnableCors] pode ser aplicado a:The [EnableCors] attribute can be applied to:

  • @No__t de página Razor-0Razor Page PageModel
  • ControladorController
  • Método de ação do controladorController action method

Você pode aplicar políticas diferentes ao controlador/página-modelo/ação com o atributo [EnableCors].You can apply different policies to controller/page-model/action with the [EnableCors] attribute. Quando o atributo [EnableCors] é aplicado a um método de controladores/página-modelo/ação, e o CORS é habilitado no middleware, ambas as políticas são aplicadas.When the [EnableCors] attribute is applied to a controllers/page-model/action method, and CORS is enabled in middleware, both policies are applied. Recomendamos a combinação de políticas.We recommend against combining policies. Use o atributo [EnableCors] ou o middleware, não ambos no mesmo aplicativo.Use the [EnableCors] attribute or middleware, not both in the same app.

O código a seguir aplica uma política diferente a cada método: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();
        }
    }
}

O código a seguir cria uma política padrão CORS e uma política chamada "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();
    }
}

Desabilitar CORSDisable CORS

O atributo [DisableCors @ no__t-2 DESABILITA o CORS para o controlador/página-modelo/ação.The [DisableCors] attribute disables CORS for the controller/page-model/action.

Opções de política de CORSCORS policy options

Esta seção descreve as várias opções que podem ser definidas em uma política CORS:This section describes the various options that can be set in a CORS policy:

AddPolicy é chamado em Startup.ConfigureServices.AddPolicy is called in Startup.ConfigureServices. Para algumas opções, pode ser útil ler a seção como o CORS funciona primeiro.For some options, it may be helpful to read the How CORS works section first.

Definir as origens permitidasSet the allowed origins

AllowAnyOrigin – permite solicitações CORS de todas as origens com qualquer esquema (http ou https).AllowAnyOrigin – Allows CORS requests from all origins with any scheme (http or https). AllowAnyOrigin não é seguro porque qualquer site pode fazer solicitações entre origens para o aplicativo.AllowAnyOrigin is insecure because any website can make cross-origin requests to the app.

Observação

Especificar AllowAnyOrigin e AllowCredentials é uma configuração insegura e pode resultar em falsificação de solicitação entre sites.Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request forgery. O serviço CORS retorna uma resposta CORS inválida quando um aplicativo é configurado com ambos os métodos.The CORS service returns an invalid CORS response when an app is configured with both methods.

Observação

Especificar AllowAnyOrigin e AllowCredentials é uma configuração insegura e pode resultar em falsificação de solicitação entre sites.Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request forgery. Para um aplicativo seguro, especifique uma lista exata de origens se o cliente precisar se autorizar para acessar os recursos do servidor.For a secure app, specify an exact list of origins if the client must authorize itself to access server resources.

AllowAnyOrigin afeta as solicitações de simulação e o cabeçalho Access-Control-Allow-Origin.AllowAnyOrigin affects preflight requests and the Access-Control-Allow-Origin header. Para obter mais informações, consulte a seção solicitações de simulação .For more information, see the Preflight requests section.

SetIsOriginAllowedToAllowWildcardSubdomains – define a propriedade IsOriginAllowed da política como uma função que permite que as origens correspondam a um domínio curinga configurado ao avaliar se a origem é permitida.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();
    });

Definir os métodos HTTP permitidosSet the allowed HTTP methods

AllowAnyMethod:AllowAnyMethod:

  • Permite qualquer método HTTP:Allows any HTTP method:
  • Afeta as solicitações de simulação e o cabeçalho Access-Control-Allow-Methods.Affects preflight requests and the Access-Control-Allow-Methods header. Para obter mais informações, consulte a seção solicitações de simulação .For more information, see the Preflight requests section.

Definir os cabeçalhos de solicitação permitidosSet the allowed request headers

Para permitir que cabeçalhos específicos sejam enviados em uma solicitação CORS, chamada de cabeçalhos de solicitação de autor, chame WithHeaders e especifique os cabeçalhos permitidos: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");
    });

Para permitir todos os cabeçalhos de solicitação de autor, chame AllowAnyHeader:To allow all author request headers, call AllowAnyHeader:

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

Essa configuração afeta as solicitações de simulação e o cabeçalho Access-Control-Request-Headers.This setting affects preflight requests and the Access-Control-Request-Headers header. Para obter mais informações, consulte a seção solicitações de simulação .For more information, see the Preflight requests section.

Uma política de middleware CORS corresponde a cabeçalhos específicos especificados por WithHeaders só é possível quando os cabeçalhos enviados em Access-Control-Request-Headers correspondem exatamente aos cabeçalhos indicados em 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.

Por exemplo, considere um aplicativo configurado da seguinte maneira:For instance, consider an app configured as follows:

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

O middleware CORS recusa uma solicitação de simulação com o seguinte cabeçalho de solicitação porque Content-Language (headernames. ContentLanguage) não está listado em 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

O aplicativo retorna uma resposta de 200 OK , mas não envia os cabeçalhos CORS de volta.The app returns a 200 OK response but doesn't send the CORS headers back. Portanto, o navegador não tenta a solicitação entre origens.Therefore, the browser doesn't attempt the cross-origin request.

O middleware CORS sempre permite que quatro cabeçalhos no Access-Control-Request-Headers sejam enviados, independentemente dos valores configurados em CorsPolicy. Headers.CORS Middleware always allows four headers in the Access-Control-Request-Headers to be sent regardless of the values configured in CorsPolicy.Headers. Essa lista de cabeçalhos inclui:This list of headers includes:

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

Por exemplo, considere um aplicativo configurado da seguinte maneira:For instance, consider an app configured as follows:

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

O middleware CORS responde com êxito a uma solicitação de simulação com o seguinte cabeçalho de solicitação porque Content-Language está sempre na lista de permissões: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

Definir os cabeçalhos de resposta expostosSet the exposed response headers

Por padrão, o navegador não expõe todos os cabeçalhos de resposta ao aplicativo.By default, the browser doesn't expose all of the response headers to the app. Para obter mais informações, consulte compartilhamento de recursos entre origens do W3C (terminologia): cabeçalho de resposta simples.For more information, see W3C Cross-Origin Resource Sharing (Terminology): Simple Response Header.

Os cabeçalhos de resposta que estão disponíveis por padrão são:The response headers that are available by default are:

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

A especificação CORS chama esses cabeçalhos cabeçalhos de resposta simples.The CORS specification calls these headers simple response headers. Para disponibilizar outros cabeçalhos para o aplicativo, chame WithExposedHeaders:To make other headers available to the app, call WithExposedHeaders:

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

Credenciais em solicitações entre origensCredentials in cross-origin requests

As credenciais exigem tratamento especial em uma solicitação CORS.Credentials require special handling in a CORS request. Por padrão, o navegador não envia credenciais com uma solicitação entre origens.By default, the browser doesn't send credentials with a cross-origin request. As credenciais incluem cookies e esquemas de autenticação HTTP.Credentials include cookies and HTTP authentication schemes. Para enviar credenciais com uma solicitação entre origens, o cliente deve definir XMLHttpRequest.withCredentials como true.To send credentials with a cross-origin request, the client must set XMLHttpRequest.withCredentials to true.

Usando XMLHttpRequest diretamente:Using XMLHttpRequest directly:

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

Usando o jQuery:Using jQuery:

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

Usando a API de busca:Using the Fetch API:

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

O servidor deve permitir as credenciais.The server must allow the credentials. Para permitir credenciais entre origens, chame AllowCredentials:To allow cross-origin credentials, call AllowCredentials:

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

A resposta HTTP inclui um cabeçalho Access-Control-Allow-Credentials, que informa ao navegador que o servidor permite credenciais para uma solicitação entre origens.The HTTP response includes an Access-Control-Allow-Credentials header, which tells the browser that the server allows credentials for a cross-origin request.

Se o navegador enviar credenciais, mas a resposta não incluir um cabeçalho Access-Control-Allow-Credentials válido, o navegador não exporá a resposta ao aplicativo e a solicitação entre origens falhará.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.

Permitir credenciais entre origens é um risco de segurança.Allowing cross-origin credentials is a security risk. Um site em outro domínio pode enviar as credenciais de um usuário conectado para o aplicativo em nome do usuário sem o conhecimento do usuário.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.

A especificação CORS também indica que a definição de origens como "*" (todas as origens) é inválida se o cabeçalho Access-Control-Allow-Credentials estiver presente.The CORS specification also states that setting origins to "*" (all origins) is invalid if the Access-Control-Allow-Credentials header is present.

Solicitações de simulaçãoPreflight requests

Para algumas solicitações de CORS, o navegador envia uma solicitação adicional antes de fazer a solicitação real.For some CORS requests, the browser sends an additional request before making the actual request. Essa solicitação é chamada de uma solicitação de simulação.This request is called a preflight request. O navegador poderá ignorar a solicitação de simulação se as seguintes condições forem verdadeiras:The browser can skip the preflight request if the following conditions are true:

  • O método de solicitação é GET, HEAD ou POST.The request method is GET, HEAD, or POST.
  • O aplicativo não define cabeçalhos de solicitação diferentes de Accept, Accept-Language, Content-Language, Content-Type ou Last-Event-ID.The app doesn't set request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID.
  • O cabeçalho Content-Type, se definido, tem um dos seguintes valores:The Content-Type header, if set, has one of the following values:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

A regra nos cabeçalhos de solicitação definidos para a solicitação do cliente aplica-se aos cabeçalhos que o aplicativo define chamando setRequestHeader no objeto 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. A especificação CORS chama esses cabeçalhos de solicitação de autorde cabeçalho.The CORS specification calls these headers author request headers. A regra não se aplica aos cabeçalhos que o navegador pode definir, como User-Agent, Host ou Content-Length.The rule doesn't apply to headers the browser can set, such as User-Agent, Host, or Content-Length.

Veja a seguir um exemplo de uma solicitação de simulação: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

A solicitação de simulação usa o método de opções HTTP.The pre-flight request uses the HTTP OPTIONS method. Ele inclui dois cabeçalhos especiais:It includes two special headers:

  • Access-Control-Request-Method: o método HTTP que será usado para a solicitação real.Access-Control-Request-Method: The HTTP method that will be used for the actual request.
  • Access-Control-Request-Headers: uma lista de cabeçalhos de solicitação que o aplicativo define na solicitação real.Access-Control-Request-Headers: A list of request headers that the app sets on the actual request. Como mencionado anteriormente, isso não inclui cabeçalhos que o navegador define, como User-Agent.As stated earlier, this doesn't include headers that the browser sets, such as User-Agent.

Uma solicitação de simulação de CORS pode incluir um cabeçalho Access-Control-Request-Headers, que indica ao servidor os cabeçalhos que são enviados com a solicitação real.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.

Para permitir cabeçalhos específicos, chame WithHeaders:To allow specific headers, call WithHeaders:

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

Para permitir todos os cabeçalhos de solicitação de autor, chame AllowAnyHeader:To allow all author request headers, call AllowAnyHeader:

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

Os navegadores não são totalmente consistentes em como eles definem Access-Control-Request-Headers.Browsers aren't entirely consistent in how they set Access-Control-Request-Headers. Se você definir cabeçalhos para algo diferente de "*" (ou usar AllowAnyHeader), deverá incluir pelo menos Accept, Content-Type e Origin, além de todos os cabeçalhos personalizados aos quais você deseja dar suporte.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.

Veja a seguir um exemplo de resposta para a solicitação de simulação (supondo que o servidor permita a solicitação):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

A resposta inclui um cabeçalho Access-Control-Allow-Methods que lista os métodos permitidos e, opcionalmente, um cabeçalho Access-Control-Allow-Headers, que lista os cabeçalhos permitidos.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. Se a solicitação de simulação for realizada com sucesso, o navegador enviará a solicitação real.If the preflight request succeeds, the browser sends the actual request.

Se a solicitação de simulação for negada, o aplicativo retornará uma resposta 200 OK , mas não enviará os cabeçalhos CORS de volta.If the preflight request is denied, the app returns a 200 OK response but doesn't send the CORS headers back. Portanto, o navegador não tenta a solicitação entre origens.Therefore, the browser doesn't attempt the cross-origin request.

Definir o tempo de expiração de simulaçãoSet the preflight expiration time

O cabeçalho Access-Control-Max-Age especifica por quanto tempo a resposta à solicitação de simulação pode ser armazenada em cache.The Access-Control-Max-Age header specifies how long the response to the preflight request can be cached. Para definir esse cabeçalho, chame SetPreflightMaxAge:To set this header, call SetPreflightMaxAge:

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

Como o CORS funcionaHow CORS works

Esta seção descreve o que acontece em uma solicitação de CORS no nível das mensagens http.This section describes what happens in a CORS request at the level of the HTTP messages.

  • O CORS não é um recurso de segurança.CORS is not a security feature. O CORS é um padrão W3C que permite que um servidor Relaxe a política de mesma origem.CORS is a W3C standard that allows a server to relax the same-origin policy.
    • Por exemplo, um ator mal-intencionado poderia usar a prevenção de scripts entre sites (XSS) em seu site e executar uma solicitação entre sites para o site habilitado para CORS para roubar informações.For example, a malicious actor could use Prevent Cross-Site Scripting (XSS) against your site and execute a cross-site request to their CORS enabled site to steal information.
  • Sua API não é mais segura, permitindo CORS.Your API is not safer by allowing CORS.
    • Cabe ao cliente (navegador) impor o CORS.It's up to the client (browser) to enforce CORS. O servidor executa a solicitação e retorna a resposta, é o cliente que retorna um erro e bloqueia a resposta.The server executes the request and returns the response, it's the client that returns an error and blocks the response. Por exemplo, qualquer uma das seguintes ferramentas exibirá a resposta do servidor:For example, any of the following tools will display the server response:
  • É uma maneira de um servidor permitir que os navegadores executem uma solicitação de API de XHR ou de busca de várias origens que, de outra forma, seriam proibidas.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.
    • Os navegadores (sem CORS) não podem fazer solicitações entre origens.Browsers (without CORS) can't do cross-origin requests. Antes do CORS, JSONP foi usado para burlar essa restrição.Before CORS, JSONP was used to circumvent this restriction. JSONP não usa XHR, ele usa a marca <script> para receber a resposta.JSONP doesn't use XHR, it uses the <script> tag to receive the response. Os scripts podem ser carregados entre origens.Scripts are allowed to be loaded cross-origin.

A especificação CORS introduziu vários novos cabeçalhos HTTP que habilitam solicitações entre origens.The CORS specification introduced several new HTTP headers that enable cross-origin requests. Se um navegador oferecer suporte a CORS, ele definirá esses cabeçalhos automaticamente para solicitações entre origens.If a browser supports CORS, it sets these headers automatically for cross-origin requests. O código JavaScript personalizado não é necessário para habilitar o CORS.Custom JavaScript code isn't required to enable CORS.

Veja a seguir um exemplo de uma solicitação entre origens.The following is an example of a cross-origin request. O cabeçalho Origin fornece o domínio do site que está fazendo a solicitação.The Origin header provides the domain of the site that's making the request. O cabeçalho Origin é necessário e deve ser diferente do host.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

Se o servidor permitir a solicitação, ele definirá o cabeçalho Access-Control-Allow-Origin na resposta.If the server allows the request, it sets the Access-Control-Allow-Origin header in the response. O valor desse cabeçalho corresponde ao cabeçalho Origin da solicitação ou é o valor curinga "*", o que significa que qualquer origem é permitida: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

Se a resposta não incluir o cabeçalho Access-Control-Allow-Origin, a solicitação entre origens falhará.If the response doesn't include the Access-Control-Allow-Origin header, the cross-origin request fails. Especificamente, o navegador não permite a solicitação.Specifically, the browser disallows the request. Mesmo se o servidor retornar uma resposta bem-sucedida, o navegador não tornará a resposta disponível para o aplicativo cliente.Even if the server returns a successful response, the browser doesn't make the response available to the client app.

Testar CORSTest CORS

Para testar o CORS:To test CORS:

  1. Criar um projeto de API.Create an API project. Como alternativa, você pode baixar o exemplo.Alternatively, you can download the sample.
  2. Habilite o CORS usando uma das abordagens deste documento.Enable CORS using one of the approaches in this document. Por exemplo: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();
}

Aviso

WithOrigins("https://localhost:<port>"); só deve ser usado para testar um aplicativo de exemplo semelhante ao código de exemplo de download.WithOrigins("https://localhost:<port>"); should only be used for testing a sample app similar to the download sample code.

  1. Criar um projeto de aplicativo Web (Razor Pages ou MVC).Create a web app project (Razor Pages or MVC). O exemplo usa Razor Pages.The sample uses Razor Pages. Você pode criar o aplicativo Web na mesma solução que o projeto de API.You can create the web app in the same solution as the API project.
  2. Adicione o seguinte código realçado ao arquivo index. 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. No código anterior, substitua url: 'https://<web app>.azurewebsites.net/api/values/1', pela URL para o aplicativo implantado.In the preceding code, replace url: 'https://<web app>.azurewebsites.net/api/values/1', with the URL to the deployed app.

  2. Implante o projeto de API.Deploy the API project. Por exemplo, implante no Azure.For example, deploy to Azure.

  3. Execute o Razor Pages ou o aplicativo MVC na área de trabalho e clique no botão testar .Run the Razor Pages or MVC app from the desktop and click on the Test button. Use as ferramentas F12 para examinar mensagens de erro.Use the F12 tools to review error messages.

  4. Remova a origem do localhost de WithOrigins e implante o aplicativo.Remove the localhost origin from WithOrigins and deploy the app. Como alternativa, execute o aplicativo cliente com uma porta diferente.Alternatively, run the client app with a different port. Por exemplo, execute do Visual Studio.For example, run from Visual Studio.

  5. Teste com o aplicativo cliente.Test with the client app. As falhas de CORS retornam um erro, mas a mensagem de erro não está disponível para JavaScript.CORS failures return an error, but the error message isn't available to JavaScript. Use a guia Console nas Ferramentas F12 para ver o erro.Use the console tab in the F12 tools to see the error. Dependendo do navegador, você receberá um erro (no console de ferramentas F12) semelhante ao seguinte:Depending on the browser, you get an error (in the F12 tools console) similar to the following:

    • Usando o Microsoft Edge:Using Microsoft Edge:

      SEC7120: [CORS] a origem https://localhost:44375 não encontrou https://localhost:44375 no cabeçalho de resposta Access-Control-Allow-Origin para o recurso entre origens em 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

    • Usando o Chrome:Using Chrome:

      O acesso a XMLHttpRequest na https://webapi.azurewebsites.net/api/values/1 da origem https://localhost:44375 foi bloqueado pela política CORS: nenhum cabeçalho ' Access-Control-Allow-Origin ' está presente no recurso solicitado.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.

Os pontos de extremidade habilitados para CORS podem ser testados com uma ferramenta, como o Fiddler ou o postmaster.CORS-enabled endpoints can be tested with a tool, such as Fiddler or Postman. Ao usar uma ferramenta, a origem da solicitação especificada pelo cabeçalho Origin deve ser diferente do host que está recebendo a solicitação.When using a tool, the origin of the request specified by the Origin header must differ from the host receiving the request. Se a solicitação não for de origem cruzada com base no valor do cabeçalho Origin:If the request isn't cross-origin based on the value of the Origin header:

  • Não há necessidade de middleware de CORS para processar a solicitação.There's no need for CORS Middleware to process the request.
  • Cabeçalhos CORS não são retornados na resposta.CORS headers aren't returned in the response.

Recursos adicionaisAdditional resources