Autoriser les demandes de Cross-Origin (CORS) dans ASP.NET CoreEnable Cross-Origin Requests (CORS) in ASP.NET Core

Par Rick AndersonBy Rick Anderson

Cet article explique comment activer CORS dans une application ASP.NET Core.This article shows how to enable CORS in an ASP.NET Core app.

Sécurité des navigateurs empêche une page web d’effectuer des requêtes vers un autre domaine que celui qui a servi la page web.Browser security prevents a web page from making requests to a different domain than the one that served the web page. Cette restriction est appelée le stratégie de même origine.This restriction is called the same-origin policy. La stratégie de même origine empêche un site malveillant de lire des données sensibles à partir d’un autre site.The same-origin policy prevents a malicious site from reading sensitive data from another site. Parfois, vous souhaiterez autoriser de qu'autres sites apporter les demandes cross-origin à votre application.Sometimes, you might want to allow other sites make cross-origin requests to your app. Pour plus d’informations, consultez le article de Mozilla CORS.For more information, see the Mozilla CORS article.

Cross-Origin Resource Sharing (CORS) :Cross Origin Resource Sharing (CORS):

  • Est un W3C standard qui permet à un serveur d’assouplir la stratégie de même origine.Is a W3C standard that allows a server to relax the same-origin policy.
  • Est pas une fonctionnalité de sécurité, CORS assouplit la sécurité.Is not a security feature, CORS relaxes security. Une API n’est pas plus sûre en autorisant CORS.An API is not safer by allowing CORS. Pour plus d’informations, consultez CORS comment fonctionne.For more information, see How CORS works.
  • Permet à un serveur autoriser explicitement certaines demandes cross-origin tout en refusant d’autres.Allows a server to explicitly allow some cross-origin requests while rejecting others.
  • Est plus sûre et plus flexible que les techniques précédentes, telles que JSONP.Is safer and more flexible than earlier techniques, such as JSONP.

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)View or download sample code (how to download)

Même origineSame origin

Deux URL ont la même origine que s’ils ont des schémas identiques, les hôtes et les ports (RFC 6454).Two URLs have the same origin if they have identical schemes, hosts, and ports (RFC 6454).

Ces deux URL ayant la même origine :These two URLs have the same origin:

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

Ces URL ont différentes origines que les deux URL précédentes :These URLs have different origins than the previous two URLs:

  • https://example.net – Autre domainehttps://example.net – Different domain
  • https://www.example.com/foo.html – Autre sous-domainehttps://www.example.com/foo.html – Different subdomain
  • http://example.com/foo.html – Schéma différenthttp://example.com/foo.html – Different scheme
  • https://example.com:9000/foo.html – Port différenthttps://example.com:9000/foo.html – Different port

Internet Explorer ne considère pas le port lors de la comparaison des origines.Internet Explorer doesn't consider the port when comparing origins.

CORS avec la stratégie nommée et intergiciel (middleware)CORS with named policy and middleware

Intergiciel (middleware) CORS gère les demandes cross-origin.CORS Middleware handles cross-origin requests. Le code suivant active CORS pour toute l’application avec l’origine spécifiée :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();
    }
}

Le code précédent :The preceding code:

Le AddCors appel de méthode ajoute des services CORS au conteneur de service de l’application :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);
}

Pour plus d’informations, consultez les options de stratégie CORS dans ce document.For more information, see CORS policy options in this document .

Le CorsPolicyBuilder méthode pouvez chaîner des méthodes, comme indiqué dans le code suivant :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);
}

Le code en surbrillance suivant applique les stratégies CORS pour toutes les applications points de terminaison via l’intergiciel (middleware) CORS :The following highlighted 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();
}

Consultez activer de CORS dans les Pages Razor, contrôleurs et méthodes d’action pour appliquer la stratégie CORS au niveau de la page / / action de contrôleur.See Enable CORS in Razor Pages, controllers, and action methods to apply CORS policy at the page/controller/action level.

Remarque :Note:

  • UseCors doit être appelé avant UseMvc.UseCors must be called before UseMvc.
  • L’URL doit pas contiennent une barre oblique (/).The URL must not contain a trailing slash (/). Si l’URL se termine avec /, la comparaison retourne false et aucun en-tête n’est retourné.If the URL terminates with /, the comparison returns false and no header is returned.

Consultez Test CORS pour obtenir des instructions sur le test du code précédent.See Test CORS for instructions on testing the preceding code.

Activer CORS avec attributsEnable CORS with attributes

Le [EnableCors] attribut fournit une alternative à l’application de CORS dans le monde entier.The [EnableCors] attribute provides an alternative to applying CORS globally. Le [EnableCors] attribut Active CORS pour les points de terminaison sélectionnés, plutôt que tous les points de terminaison.The [EnableCors] attribute enables CORS for selected end points, rather than all end points.

Utilisez [EnableCors] pour spécifier la stratégie par défaut et [EnableCors("{Policy String}")] pour spécifier une stratégie.Use [EnableCors] to specify the default policy and [EnableCors("{Policy String}")] to specify a policy.

Le [EnableCors] attribut peut être appliqué aux :The [EnableCors] attribute can be applied to:

  • Page Razor PageModelRazor Page PageModel
  • ContrôleurController
  • Méthode d’action de contrôleurController action method

Vous pouvez appliquer des stratégies différentes à contrôleur/page-modèle/une action avec la [EnableCors] attribut.You can apply different policies to controller/page-model/action with the [EnableCors] attribute. Lorsque le [EnableCors] attribut est appliqué à une méthode d’action/modèle-page/contrôleurs et CORS est activé dans l’intergiciel (middleware), les deux stratégies sont appliquées.When the [EnableCors] attribute is applied to a controllers/page-model/action method, and CORS is enabled in middleware, both policies are applied. Nous déconseillons de combinaison de stratégies.We recommend against combining policies. Utilisez le [EnableCors] attribut ou un intergiciel (middleware), pas à la fois dans la même application.Use the [EnableCors] attribute or middleware, not both in the same app.

Le code suivant applique une stratégie différente à chaque méthode :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();
        }
    }
}

Le code suivant crée une stratégie par défaut CORS et une stratégie nommée "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();
    }
}

Désactiver CORSDisable CORS

Le [DisableCors] attribut désactive CORS pour la contrôleur/page-modèle/une action.The [DisableCors] attribute disables CORS for the controller/page-model/action.

Options de stratégie CORSCORS policy options

Cette section décrit les différentes options qui peuvent être définies dans une stratégie CORS :This section describes the various options that can be set in a CORS policy:

AddPolicy est appelé dans Startup.ConfigureServices.AddPolicy is called in Startup.ConfigureServices. Pour certaines options, il peut être utile de lire le CORS comment fonctionne section tout d’abord.For some options, it may be helpful to read the How CORS works section first.

Définir les origines autoriséesSet the allowed origins

AllowAnyOrigin – Autorise les demandes CORS à partir de toutes les origines avec n’importe quel schéma (http ou https).AllowAnyOrigin – Allows CORS requests from all origins with any scheme (http or https). AllowAnyOrigin n’est pas sécurisé, car n’importe quel site Web peut apporter les demandes cross-origin à l’application.AllowAnyOrigin is insecure because any website can make cross-origin requests to the app.

Notes

Spécification AllowAnyOrigin et AllowCredentials est une configuration non sécurisée et peut entraîner la falsification de requête intersites.Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request forgery. Le service CORS retourne une réponse non valide de CORS lorsqu’une application est configurée avec les deux méthodes.The CORS service returns an invalid CORS response when an app is configured with both methods.

Notes

Spécification AllowAnyOrigin et AllowCredentials est une configuration non sécurisée et peut entraîner la falsification de requête intersites.Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request forgery. Pour une application sécurisée, spécifiez une liste exacte des origines si le client doit autoriser lui-même pour accéder aux ressources du serveur.For a secure app, specify an exact list of origins if the client must authorize itself to access server resources.

AllowAnyOrigin affecte des demandes de contrôle en amont et le Access-Control-Allow-Origin en-tête.AllowAnyOrigin affects preflight requests and the Access-Control-Allow-Origin header. Pour plus d’informations, consultez le demandes de contrôle en amont section.For more information, see the Preflight requests section.

SetIsOriginAllowedToAllowWildcardSubdomains – Définit le IsOriginAllowed propriété de la stratégie comme étant une fonction qui autorise les origines correspondre à un domaine générique configuré lors de l’évaluation si l’origine est autorisée.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.SetIsOriginAllowedToAllowWildcardSubdomains();
    });

Définir les méthodes HTTP autoriséesSet the allowed HTTP methods

AllowAnyMethod:AllowAnyMethod:

  • Permet de n’importe quelle méthode HTTP :Allows any HTTP method:
  • Affecte des demandes de contrôle en amont et le Access-Control-Allow-Methods en-tête.Affects preflight requests and the Access-Control-Allow-Methods header. Pour plus d’informations, consultez le demandes de contrôle en amont section.For more information, see the Preflight requests section.

Définir les en-têtes de requêteSet the allowed request headers

Pour autoriser des en-têtes spécifiques à envoyer dans une demande CORS, appelé créer des en-têtes de demande, appelez WithHeaders et spécifiez les en-têtes autorisés :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");
    });

Pour autoriser tous les créer des en-têtes de demande, appelez AllowAnyHeader:To allow all author request headers, call AllowAnyHeader:

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

Ce paramètre affecte les demandes préliminaires et Access-Control-Request-Headers en-tête.This setting affects preflight requests and the Access-Control-Request-Headers header. Pour plus d’informations, consultez le demandes de contrôle en amont section.For more information, see the Preflight requests section.

Une recherche de correspondance de stratégie intergiciel (middleware) CORS spécifiée par des en-têtes spécifiques WithHeaders n’est possible que lorsque les en-têtes envoyés Access-Control-Request-Headers correspondre exactement les en-têtes indiqués dans 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.

Par exemple, considérez une application configurée comme suit :For instance, consider an app configured as follows:

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

Intergiciel (middleware) CORS refuse une demande préliminaire avec l’en-tête de demande suivant, car Content-Language (HeaderNames.ContentLanguage) n’est pas répertoriée dans 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

L’application retourne un 200 OK réponse mais n’envoie pas les en-têtes CORS précédent.The app returns a 200 OK response but doesn't send the CORS headers back. Par conséquent, le navigateur ne tente pas la demande cross-origin.Therefore, the browser doesn't attempt the cross-origin request.

Intergiciel (middleware) CORS permet toujours quatre en-têtes dans le Access-Control-Request-Headers à envoyer, indépendamment des valeurs configurées dans 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. Cette liste d’en-têtes comprend :This list of headers includes:

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

Par exemple, considérez une application configurée comme suit :For instance, consider an app configured as follows:

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

Intergiciel (middleware) CORS répond correctement à une demande préliminaire avec l’en-tête de demande suivant, car Content-Language est toujours dans la liste verte :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

Définir les en-têtes de réponse exposéSet the exposed response headers

Par défaut, le navigateur n’expose pas tous les en-têtes de réponse à l’application.By default, the browser doesn't expose all of the response headers to the app. Pour plus d’informations, consultez W3C Cross-Origin Resource Sharing (terminologie) : En-tête de réponse simple.For more information, see W3C Cross-Origin Resource Sharing (Terminology): Simple Response Header.

Les en-têtes de réponse sont disponibles par défaut sont :The response headers that are available by default are:

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

La spécification CORS appelle ces en-têtes les en-têtes de réponse simple.The CORS specification calls these headers simple response headers. Pour les autres en-têtes disponibles pour l’application, appelez WithExposedHeaders:To make other headers available to the app, call WithExposedHeaders:

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

Informations d’identification dans les demandes cross-originCredentials in cross-origin requests

Les informations d’identification nécessitent un traitement particulier dans une demande CORS.Credentials require special handling in a CORS request. Par défaut, le navigateur n’envoie pas les informations d’identification avec une demande de cross-origin.By default, the browser doesn't send credentials with a cross-origin request. Informations d’identification incluent les cookies et les schémas d’authentification HTTP.Credentials include cookies and HTTP authentication schemes. Pour envoyer des informations d’identification avec une demande de cross-origin, le client doit définir XMLHttpRequest.withCredentials à true.To send credentials with a cross-origin request, the client must set XMLHttpRequest.withCredentials to true.

À l’aide de XMLHttpRequest directement :Using XMLHttpRequest directly:

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

À l’aide de jQuery :Using jQuery:

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

À l’aide de la obtenir l’API:Using the Fetch API:

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

Le serveur doit autoriser les informations d’identification.The server must allow the credentials. Pour autoriser les informations d’identification de cross-origin, appeler AllowCredentials:To allow cross-origin credentials, call AllowCredentials:

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

La réponse HTTP inclut un Access-Control-Allow-Credentials en-tête, qui indique au navigateur que le serveur autorise les informations d’identification pour une demande de cross-origin.The HTTP response includes an Access-Control-Allow-Credentials header, which tells the browser that the server allows credentials for a cross-origin request.

Si le navigateur envoie les informations d’identification, mais la réponse n’inclut pas une valide Access-Control-Allow-Credentials en-tête, le navigateur n’expose pas la réponse à l’application, et la demande cross-origin échoue.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.

Autoriser les informations d’identification de cross-origin est un risque de sécurité.Allowing cross-origin credentials is a security risk. Un site Web à un autre domaine peut envoyer des informations d’identification d’un utilisateur de connecté à l’application sur l’utilisateur sans avoir connaissance de l’utilisateur.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.

La spécification CORS indique également ce paramètre pour les origines "*" (toutes les origines) n’est pas valide si le Access-Control-Allow-Credentials en-tête est présent.The CORS specification also states that setting origins to "*" (all origins) is invalid if the Access-Control-Allow-Credentials header is present.

Demandes préliminairesPreflight requests

Pour certaines requêtes CORS, le navigateur envoie une demande supplémentaire avant d’effectuer la demande réelle.For some CORS requests, the browser sends an additional request before making the actual request. Cette requête est appelée un demande préliminaire.This request is called a preflight request. Le navigateur peut ignorer la demande préliminaire si les conditions suivantes sont remplies :The browser can skip the preflight request if the following conditions are true:

  • La méthode de demande est GET, HEAD ou POST.The request method is GET, HEAD, or POST.
  • L’application ne définit pas les en-têtes de demande autre que 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.
  • Le Content-Type en-tête, si définis, dispose d’une des valeurs suivantes :The Content-Type header, if set, has one of the following values:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

La règle sur les en-têtes de requête définie pour la demande du client s’applique aux en-têtes de l’application définit en appelant setRequestHeader sur la XMLHttpRequest objet.The rule on request headers set for the client request applies to headers that the app sets by calling setRequestHeader on the XMLHttpRequest object. La spécification CORS appelle ces en-têtes créer des en-têtes de demande.The CORS specification calls these headers author request headers. La règle ne s’applique pas aux en-têtes le navigateur peut définir comme 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.

Voici un exemple d’une requête préliminaire :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

La demande de contrôle préliminaire utilise la méthode HTTP OPTIONS.The pre-flight request uses the HTTP OPTIONS method. Il comprend deux en-têtes spéciaux :It includes two special headers:

  • Access-Control-Request-Method: La méthode HTTP qui sera utilisée pour la demande réelle.Access-Control-Request-Method: The HTTP method that will be used for the actual request.
  • Access-Control-Request-Headers: Liste des en-têtes de demande que l’application définit sur la demande réelle.Access-Control-Request-Headers: A list of request headers that the app sets on the actual request. Comme indiqué précédemment, cela n’inclut pas les en-têtes qui définit le navigateur, telles que User-Agent.As stated earlier, this doesn't include headers that the browser sets, such as User-Agent.

Une demande préliminaire CORS peut inclure un Access-Control-Request-Headers en-tête, qui indique au serveur les en-têtes qui sont envoyées avec la demande réelle.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.

Pour autoriser des en-têtes spécifiques, appeler WithHeaders:To allow specific headers, call WithHeaders:

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

Pour autoriser tous les créer des en-têtes de demande, appelez AllowAnyHeader:To allow all author request headers, call AllowAnyHeader:

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

Navigateurs ne sont pas entièrement cohérents dans la façon dont elles définies Access-Control-Request-Headers.Browsers aren't entirely consistent in how they set Access-Control-Request-Headers. Si vous définissez les en-têtes sur n’importe quelle autre que "*" (ou utilisez AllowAnyHeader), vous devez inclure au moins Accept, Content-Type, et Origin, ainsi que tous les en-têtes personnalisés que vous souhaitez prendre en charge.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.

Voici un exemple de réponse à la demande préliminaire (en supposant que le serveur autorise la demande) :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

La réponse inclut un Access-Control-Allow-Methods en-tête qui répertorie les méthodes autorisées et éventuellement un Access-Control-Allow-Headers en-tête qui répertorie les en-têtes autorisés.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. Si la demande préliminaire réussit, le navigateur envoie la demande réelle.If the preflight request succeeds, the browser sends the actual request.

Si la demande préliminaire est refusée, l’application retourne un 200 OK réponse mais n’envoie pas les en-têtes CORS précédent.If the preflight request is denied, the app returns a 200 OK response but doesn't send the CORS headers back. Par conséquent, le navigateur ne tente pas la demande cross-origin.Therefore, the browser doesn't attempt the cross-origin request.

Définir en amont le délai d’expirationSet the preflight expiration time

Le Access-Control-Max-Age en-tête spécifie la durée pendant laquelle la réponse à la demande préliminaire peut être mis en cache.The Access-Control-Max-Age header specifies how long the response to the preflight request can be cached. Pour définir cet en-tête, appelez SetPreflightMaxAge:To set this header, call SetPreflightMaxAge:

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

Fonctionnement de CORSHow CORS works

Cette section décrit ce qui se passe dans un CORS demande au niveau des messages HTTP.This section describes what happens in a CORS request at the level of the HTTP messages.

  • CORS est pas une fonctionnalité de sécurité.CORS is not a security feature. CORS est une norme W3C qui permet à un serveur d’assouplir la stratégie de même origine.CORS is a W3C standard that allows a server to relax the same-origin policy.
    • Par exemple, un acteur malveillant pourrait utiliser empêcher Cross-Site Scripting (XSS) par rapport à votre site avant d’exécuter une requête intersites à leur site CORS est activé pour dérober des informations.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.
  • Votre API n’est pas plus sûre en autorisant CORS.Your API is not safer by allowing CORS.
    • C’est à appliquer CORS pour le client (navigateur).It's up to the client (browser) to enforce CORS. Le serveur exécute la requête et renvoie la réponse, c’est le client qui renvoie une erreur et les blocs de la réponse.The server executes the request and returns the response, it's the client that returns an error and blocks the response. Par exemple, un des outils suivants affiche la réponse du serveur :For example, any of the following tools will display the server response:
  • C’est un moyen pour un serveur pour permettre des navigateurs pour exécuter une cross-origine XHR ou API Fetch demande sinon est interdite.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.
    • Navigateurs (sans CORS) ne peut pas faire des demandes cross-origin.Browsers (without CORS) can't do cross-origin requests. Avant de CORS, JSONP a été utilisé pour contourner cette restriction.Before CORS, JSONP was used to circumvent this restriction. JSONP n’utilise pas XHR, il utilise le <script> balise pour recevoir la réponse.JSONP doesn't use XHR, it uses the <script> tag to receive the response. Les scripts sont autorisés à être chargé cross-origin.Scripts are allowed to be loaded cross-origin.

Le spécification CORS introduit plusieurs nouveaux en-têtes HTTP qui permettent les requêtes cross-origin.The CORS specification introduced several new HTTP headers that enable cross-origin requests. Si un navigateur prend en charge CORS, il définit ces en-têtes automatiquement pour les demandes cross-origin.If a browser supports CORS, it sets these headers automatically for cross-origin requests. Du code JavaScript personnalisé n’est pas nécessaire pour activer CORS.Custom JavaScript code isn't required to enable CORS.

Voici un exemple d’une demande de cross-origin.The following is an example of a cross-origin request. Le Origin en-tête fournit le domaine du site qui effectue la demande :The Origin header provides the domain of the site that's making the request:

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

Si le serveur autorise la demande, il définit le Access-Control-Allow-Origin en-tête dans la réponse.If the server allows the request, it sets the Access-Control-Allow-Origin header in the response. La valeur de cet en-tête correspond soit à la Origin en-tête à partir de la demande, soit la valeur de caractère générique "*", ce qui signifie que toute origine est autorisée :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

Si la réponse n’inclut pas le Access-Control-Allow-Origin en-tête, la demande cross-origin échoue.If the response doesn't include the Access-Control-Allow-Origin header, the cross-origin request fails. Plus précisément, le navigateur n’autorise pas la demande.Specifically, the browser disallows the request. Même si le serveur retourne une réponse correcte, le navigateur ne rend pas la réponse disponible dans l’application cliente.Even if the server returns a successful response, the browser doesn't make the response available to the client app.

Testez CORSTest CORS

Pour tester CORS :To test CORS:

  1. Créer un projet d’API.Create an API project. Vous pouvez également télécharger l’exemple.Alternatively, you can download the sample.
  2. Activer CORS à l’aide d’une des approches dans ce document.Enable CORS using one of the approaches in this document. Exemple :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();
}

Avertissement

WithOrigins("https://localhost:<port>"); doit uniquement être utilisé pour tester un exemple d’application similaire à la télécharger l’exemple de code.WithOrigins("https://localhost:<port>"); should only be used for testing a sample app similar to the download sample code.

  1. Créer un projet d’application web (Pages Razor ou MVC).Create a web app project (Razor Pages or MVC). L’exemple utilise les Pages Razor.The sample uses Razor Pages. Vous pouvez créer l’application web dans la même solution que le projet d’API.You can create the web app in the same solution as the API project.
  2. Ajoutez le code en surbrillance suivant à la Index.cshtml fichier :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. Dans le code précédent, remplacez url: 'https://<web app>.azurewebsites.net/api/values/1', par l’URL de l’application déployée.In the preceding code, replace url: 'https://<web app>.azurewebsites.net/api/values/1', with the URL to the deployed app.

  2. Déployer le projet d’API.Deploy the API project. Par exemple, déployer vers Azure.For example, deploy to Azure.

  3. Exécutez l’application Pages Razor ou MVC à partir du bureau et cliquez sur le Test bouton.Run the Razor Pages or MVC app from the desktop and click on the Test button. Utiliser les outils F12 pour passer en revue les messages d’erreur.Use the F12 tools to review error messages.

  4. Supprimer l’origine de localhost à partir de WithOrigins et déployer l’application.Remove the localhost origin from WithOrigins and deploy the app. Vous pouvez également exécuter l’application cliente avec un autre port.Alternatively, run the client app with a different port. Par exemple, exécutez à partir de Visual Studio.For example, run from Visual Studio.

  5. Tester avec l’application cliente.Test with the client app. Défaillances CORS renvoient une erreur, mais le message d’erreur n’est pas disponible à JavaScript.CORS failures return an error, but the error message isn't available to JavaScript. Utilisez l’onglet de la console dans les outils F12 pour afficher l’erreur.Use the console tab in the F12 tools to see the error. Selon le navigateur, vous obtenez une erreur (dans la console Outils F12) similaire à ce qui suit :Depending on the browser, you get an error (in the F12 tools console) similar to the following:

    • À l’aide de Microsoft Edge :Using Microsoft Edge:

      SEC7120 : [CORS] l’origine https://localhost:44375 n’a pas trouvé https://localhost:44375 dans l’en-tête de réponse Access-Control-Allow-Origin pour des ressources cross-origin à 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

    • À l’aide de Chrome :Using Chrome:

      Accès à XMLHttpRequest au https://webapi.azurewebsites.net/api/values/1 à partir de l’origine https://localhost:44375 a été bloqué par la stratégie CORS : Aucun en-tête 'Access-Control-Allow-Origin' n’est présent sur la ressource demandée.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.

Ressources supplémentairesAdditional resources