Configurer ASP.NET Core pour l’utilisation de serveurs proxy et d’équilibreurs de chargeConfigure ASP.NET Core to work with proxy servers and load balancers

Par Luke Latham et Chris RossBy Luke Latham and Chris Ross

Dans la configuration recommandée d’ASP.NET Core, l’application est hébergée à l’aide du module IIS/ASP.NET Core, de Nginx ou d’Apache.In the recommended configuration for ASP.NET Core, the app is hosted using IIS/ASP.NET Core Module, Nginx, or Apache. Les serveurs proxy, les équilibreurs de charge et autres dispositifs réseau masquent souvent les informations sur la requête avant qu’elle n’atteigne l’application :Proxy servers, load balancers, and other network appliances often obscure information about the request before it reaches the app:

  • Quand les requêtes HTTPS sont transmises par proxy via HTTP, le schéma d’origine (HTTPS) est perdu et doit être transféré dans un en-tête.When HTTPS requests are proxied over HTTP, the original scheme (HTTPS) is lost and must be forwarded in a header.
  • Étant donné qu’une requête adressée à une application transite par le proxy au lieu de provenir directement de sa source sur Internet ou le réseau d’entreprise, l’adresse IP cliente d’origine doit également être transférée dans un en-tête.Because an app receives a request from the proxy and not its true source on the Internet or corporate network, the originating client IP address must also be forwarded in a header.

Ces informations peuvent être importantes pour traiter les requêtes, par exemple dans les redirections, l’authentification, la génération de lien, l’évaluation des stratégies et la géolocalisation des clients.This information may be important in request processing, for example in redirects, authentication, link generation, policy evaluation, and client geolocation.

En-têtes transférésForwarded headers

Par convention, les proxys transfèrent les informations dans des en-têtes HTTP.By convention, proxies forward information in HTTP headers.

HeaderHeader DescriptionDescription
X-Forwarded-ForX-Forwarded-For Contient des informations sur le client à l’origine de la requête et les proxys suivants dans une chaîne de proxys.Holds information about the client that initiated the request and subsequent proxies in a chain of proxies. Ce paramètre peut contenir des adresses IP (et, éventuellement, des numéros de port).This parameter may contain IP addresses (and, optionally, port numbers). Dans une chaîne de serveurs proxy, le premier paramètre indique le client sur lequel la requête a été effectuée pour la première fois.In a chain of proxy servers, the first parameter indicates the client where the request was first made. Viennent ensuite les identificateurs des proxy suivants.Subsequent proxy identifiers follow. Le dernier proxy dans la chaîne ne figure pas dans la liste des paramètres.The last proxy in the chain isn't in the list of parameters. L’adresse IP du dernier proxy et éventuellement un numéro de port sont disponibles en tant qu’adresse IP distante au niveau de la couche transport.The last proxy's IP address, and optionally a port number, are available as the remote IP address at the transport layer.
X-Forwarded-ProtoX-Forwarded-Proto Valeur du schéma d’origine (HTTP/HTTPS).The value of the originating scheme (HTTP/HTTPS). La valeur peut également être une liste de schémas si la requête a franchi plusieurs proxys.The value may also be a list of schemes if the request has traversed multiple proxies.
X-Forwarded-HostX-Forwarded-Host Valeur d’origine du champ d’en-tête de l’hôte.The original value of the Host header field. En règle générale, les proxys ne modifient pas l’en-tête de l’hôte.Usually, proxies don't modify the Host header. Consultez le document Microsoft Security Advisory CVE-2018-0787 pour plus d’informations sur une vulnérabilité par élévation de privilèges qui affecte les systèmes où le proxy ne valide pas les en-têtes d’hôte ou ne les limite pas à des valeurs correctes connues.See Microsoft Security Advisory CVE-2018-0787 for information on an elevation-of-privileges vulnerability that affects systems where the proxy doesn't validate or restrict Host headers to known good values.

Le middleware (intergiciel) des en-têtes transférés, dans le package Microsoft.AspNetCore.HttpOverrides, lit ces en-têtes et renseigne les champs associés sur HttpContext.The Forwarded Headers Middleware, from the Microsoft.AspNetCore.HttpOverrides package, reads these headers and fills in the associated fields on HttpContext.

Le middleware met à jour les éléments suivants :The middleware updates:

Vous pouvez configurer les paramètres par défaut du middleware des en-têtes transférés.Forwarded Headers Middleware default settings can be configured. Le paramétrage par défaut est le suivant :The default settings are:

  • Il y a un seul proxy entre l’application et la source des requêtes.There is only one proxy between the app and the source of the requests.
  • Seules des adresses de bouclage sont configurées pour les proxys connus et les réseaux connus.Only loopback addresses are configured for known proxies and known networks.
  • Les en-têtes transférés sont nommés X-Forwarded-For et X-Forwarded-Proto.The forwarded headers are named X-Forwarded-For and X-Forwarded-Proto.

Certaines appliances réseau nécessitent une configuration supplémentaire pour ajouter les en-têtes X-Forwarded-For et X-Forwarded-Proto.Not all network appliances add the X-Forwarded-For and X-Forwarded-Proto headers without additional configuration. Consultez les instructions du fabricant de votre appliance si des requêtes en proxy ne contiennent pas ces en-têtes quand elles atteignent l’application.Consult your appliance manufacturer's guidance if proxied requests don't contain these headers when they reach the app. Si l’appliance utilise des noms d’en-têtes autres que X-Forwarded-For et X-Forwarded-Proto, définissez les options ForwardedForHeaderName et ForwardedProtoHeaderName pour faire correspondre les noms d’en-têtes utilisés par l’appliance.If the appliance uses different header names than X-Forwarded-For and X-Forwarded-Proto, set the ForwardedForHeaderName and ForwardedProtoHeaderName options to match the header names used by the appliance. Pour plus d’informations, consultez Options du middleware des en-têtes transférés et Configuration d’un proxy qui utilise des noms d’en-têtes différents.For more information, see Forwarded Headers Middleware options and Configuration for a proxy that uses different header names.

Module ASP.NET Core et IIS/IIS ExpressIIS/IIS Express and ASP.NET Core Module

Le middleware des en-têtes transférés est activé par défaut par le middleware d’intégration IIS quand l’application est exécutée derrière IIS et le module ASP.NET Core.Forwarded Headers Middleware is enabled by default by IIS Integration Middleware when the app is run behind IIS and the ASP.NET Core Module. Le middleware des en-têtes transférés est activé pour s’exécuter en premier dans le pipeline des middlewares avec une configuration limitée propre au module ASP.NET Core en raison de problèmes d’approbation liés aux en-têtes transférés (par exemple, usurpation d’adresse IP).Forwarded Headers Middleware is activated to run first in the middleware pipeline with a restricted configuration specific to the ASP.NET Core Module due to trust concerns with forwarded headers (for example, IP spoofing). Le middleware est configuré pour transférer les en-têtes X-Forwarded-For et X-Forwarded-Proto et est limité à un proxy localhost unique.The middleware is configured to forward the X-Forwarded-For and X-Forwarded-Proto headers and is restricted to a single localhost proxy. Si une configuration supplémentaire est requise, consultez les options du middleware des en-têtes transférés.If additional configuration is required, see the Forwarded Headers Middleware options.

Autres scénarios avec un serveur proxy et un équilibreur de chargeOther proxy server and load balancer scenarios

En dehors de l’utilisation du middleware d’intégration IIS, le middleware des en-têtes transférés n’est pas activé par défaut.Outside of using IIS Integration Middleware, Forwarded Headers Middleware isn't enabled by default. Le middleware des en-têtes transférés doit être activé pour qu’une application puisse traiter les en-têtes transférés avec UseForwardedHeaders.Forwarded Headers Middleware must be enabled for an app to process forwarded headers with UseForwardedHeaders. Une fois activé le middleware si aucune option ForwardedHeadersOptions ne lui est spécifiée, les propriétés ForwardedHeadersOptions.ForwardedHeaders par défaut ont pour valeur ForwardedHeaders.None.After enabling the middleware if no ForwardedHeadersOptions are specified to the middleware, the default ForwardedHeadersOptions.ForwardedHeaders are ForwardedHeaders.None.

Configurez le middleware avec ForwardedHeadersOptions pour transférer les en-têtes X-Forwarded-For et X-Forwarded-Proto dans Startup.ConfigureServices.Configure the middleware with ForwardedHeadersOptions to forward the X-Forwarded-For and X-Forwarded-Proto headers in Startup.ConfigureServices. Appelez la méthode UseForwardedHeaders dans Startup.Configure avant d’appeler d’autres middlewares :Invoke the UseForwardedHeaders method in Startup.Configure before calling other middleware:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = 
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseForwardedHeaders();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();
    // In ASP.NET Core 1.x, replace the following line with: app.UseIdentity();
    app.UseAuthentication();
    app.UseMvc();
}

Notes

Si aucune option ForwardedHeadersOptions n’est spécifiée dans Startup.ConfigureServices ou directement dans la méthode d’extension avec UseForwardedHeaders(IApplicationBuilder, ForwardedHeadersOptions), les en-têtes par défaut à transférer ont pour valeur ForwardedHeaders.None.If no ForwardedHeadersOptions are specified in Startup.ConfigureServices or directly to the extension method with UseForwardedHeaders(IApplicationBuilder, ForwardedHeadersOptions), the default headers to forward are ForwardedHeaders.None. La propriété ForwardedHeadersOptions.ForwardedHeaders doit être configurée avec les en-têtes à transférer.The ForwardedHeadersOptions.ForwardedHeaders property must be configured with the headers to forward.

Configuration de NginxNginx configuration

Pour transférer les en-têtes X-Forwarded-For et X-Forwarded-Proto, consultez Héberger ASP.NET Core sur Linux avec Nginx.To forward the X-Forwarded-For and X-Forwarded-Proto headers, see Héberger ASP.NET Core sur Linux avec Nginx. Pour plus d’informations, consultez NGINX : utilisation de l’en-tête Forwarded.For more information, see NGINX: Using the Forwarded header.

Configuration d’ApacheApache configuration

X-Forwarded-For est ajouté automatiquement (consultez Module Apache mod_proxy : en-têtes de requête du mandataire inverse).X-Forwarded-For is added automatically (see Apache Module mod_proxy: Reverse Proxy Request Headers). Pour plus d’informations sur la façon de transférer l’en-tête X-Forwarded-Proto, consultez Héberger ASP.NET Core sur Linux avec Apache.For information on how to forward the X-Forwarded-Proto header, see Héberger ASP.NET Core sur Linux avec Apache.

Options du middleware des en-têtes transférésForwarded Headers Middleware options

Les options ForwardedHeadersOptions contrôlent le comportement du middleware des en-têtes transférés.ForwardedHeadersOptions control the behavior of the Forwarded Headers Middleware. L’exemple suivant change les valeurs par défaut :The following example changes the default values:

  • Limitez le nombre d’entrées dans les en-têtes transférés à 2.Limit the number of entries in the forwarded headers to 2.
  • Ajoutez l’adresse de proxy connue 127.0.10.1.Add a known proxy address of 127.0.10.1.
  • Changez le nom de l’en-tête transféré en remplaçant la valeur par défaut X-Forwarded-For par X-Forwarded-For-My-Custom-Header-Name.Change the forwarded header name from the default X-Forwarded-For to X-Forwarded-For-My-Custom-Header-Name.
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardLimit = 2;
    options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
    options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});
OptionOption DescriptionDescription
AllowedHostsAllowedHosts Limite les hôtes par l’en-tête X-Forwarded-Host aux valeurs fournies.Restricts hosts by the X-Forwarded-Host header to the values provided.
  • Les valeurs sont comparées à l’aide de l’option ordinal-ignore-case.Values are compared using ordinal-ignore-case.
  • Les numéros de port doivent être exclus.Port numbers must be excluded.
  • Si la liste est vide, tous les hôtes sont autorisés.If the list is empty, all hosts are allowed.
  • Un caractère générique de niveau supérieur * autorise tous les hôtes non vides.A top-level wildcard * allows all non-empty hosts.
  • Les caractères génériques de sous-domaine sont autorisés, mais ne correspondent pas au domaine racine.Subdomain wildcards are permitted but don't match the root domain. Par exemple, *.contoso.com correspond au sous-domaine foo.contoso.com, mais pas au domaine racine contoso.com.For example, *.contoso.com matches the subdomain foo.contoso.com but not the root domain contoso.com.
  • Les noms d’hôte Unicode sont autorisés, mais sont convertis en Punycode à des fins de correspondance.Unicode host names are allowed but are converted to Punycode for matching.
  • Les adresses IPv6 doivent inclure des crochets de délimitation et adopter une forme conventionnelle (par exemple, [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]).IPv6 addresses must include bounding brackets and be in conventional form (for example, [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). Les adresses IPv6 ne sont pas les seules à rechercher une égalité logique entre différents formats, et aucune canonicalisation n’est effectuée.IPv6 addresses aren't special-cased to check for logical equality between different formats, and no canonicalization is performed.
  • La non-restriction des hôtes autorisés peut permettre à un attaquant d’usurper les liens générés par le service.Failure to restrict the allowed hosts may allow an attacker to spoof links generated by the service.
La valeur par défaut est un IList<string> vide.The default value is an empty IList<string>.
ForwardedForHeaderNameForwardedForHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XForwardedForHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedForHeaderName. Cette option est utilisée quand le proxy/redirecteur utilise un en-tête autre que l’en-tête X-Forwarded-For pour transférer les informations.This option is used when the proxy/forwarder doesn't use the X-Forwarded-For header but uses some other header to forward the information.

La valeur par défaut est X-Forwarded-For.The default is X-Forwarded-For.
ForwardedHeadersForwardedHeaders Identifie les redirecteurs à traiter.Identifies which forwarders should be processed. Consultez l’énumération ForwardedHeaders pour obtenir la liste des champs qui s’appliquent.See the ForwardedHeaders Enum for the list of fields that apply. En règle générale, les valeurs attribuées à cette propriété sont ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.Typical values assigned to this property are ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

La valeur par défaut est ForwardedHeaders.None.The default value is ForwardedHeaders.None.
ForwardedHostHeaderNameForwardedHostHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XForwardedHostHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedHostHeaderName. Cette option est utilisée quand le proxy/redirecteur utilise un en-tête autre que l’en-tête X-Forwarded-Host pour transférer les informations.This option is used when the proxy/forwarder doesn't use the X-Forwarded-Host header but uses some other header to forward the information.

La valeur par défaut est X-Forwarded-Host.The default is X-Forwarded-Host.
ForwardedProtoHeaderNameForwardedProtoHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XForwardedProtoHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedProtoHeaderName. Cette option est utilisée quand le proxy/redirecteur utilise un en-tête autre que l’en-tête X-Forwarded-Proto pour transférer les informations.This option is used when the proxy/forwarder doesn't use the X-Forwarded-Proto header but uses some other header to forward the information.

La valeur par défaut est X-Forwarded-Proto.The default is X-Forwarded-Proto.
ForwardLimitForwardLimit Limite le nombre d’entrées dans les en-têtes qui sont traités.Limits the number of entries in the headers that are processed. Définissez cette option sur null pour désactiver la limite, mais seulement si KnownProxies ou KnownNetworks sont configurés.Set to null to disable the limit, but this should only be done if KnownProxies or KnownNetworks are configured.

La valeur par défaut est 1.The default is 1.
KnownNetworksKnownNetworks Plages d’adresses des réseaux connus à partir desquels les en-têtes transférés peuvent être acceptés.Address ranges of known networks to accept forwarded headers from. Indiquez les plages d’adresses IP à l’aide de la notation CIDR (Classless Interdomain Routing).Provide IP ranges using Classless Interdomain Routing (CIDR) notation.

Si le serveur utilise des sockets en mode double, les adresses IPv4 sont fournies dans un format IPv6 (par exemple, 10.0.0.1 dans IPv4 représentée dans IPv6 en tant que ::ffff:10.0.0.1).If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1). Consultez IPAddress.MapToIPv6.See IPAddress.MapToIPv6. Déterminez si ce format est nécessaire en examinant HttpContext.Connection.RemoteIpAddress.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. Pour plus d’informations, consultez la section Configuration pour une adresse IPv4 représentée sous la forme d’une adresse IPv6.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

La valeur par défaut est un IList<IPNetwork> contenant une seule entrée pour IPAddress.Loopback.The default is an IList<IPNetwork> containing a single entry for IPAddress.Loopback.
KnownProxiesKnownProxies Adresses des proxy connus à partir desquels les en-têtes transférés peuvent être acceptés.Addresses of known proxies to accept forwarded headers from. Utilisez KnownProxies pour spécifier des correspondances d’adresse IP exactes.Use KnownProxies to specify exact IP address matches.

Si le serveur utilise des sockets en mode double, les adresses IPv4 sont fournies dans un format IPv6 (par exemple, 10.0.0.1 dans IPv4 représentée dans IPv6 en tant que ::ffff:10.0.0.1).If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1). Consultez IPAddress.MapToIPv6.See IPAddress.MapToIPv6. Déterminez si ce format est nécessaire en examinant HttpContext.Connection.RemoteIpAddress.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. Pour plus d’informations, consultez la section Configuration pour une adresse IPv4 représentée sous la forme d’une adresse IPv6.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

La valeur par défaut est un IList<IPAddress> contenant une seule entrée pour IPAddress.IPv6Loopback.The default is an IList<IPAddress> containing a single entry for IPAddress.IPv6Loopback.
OriginalForHeaderNameOriginalForHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XOriginalForHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalForHeaderName.

La valeur par défaut est X-Original-For.The default is X-Original-For.
OriginalHostHeaderNameOriginalHostHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XOriginalHostHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalHostHeaderName.

La valeur par défaut est X-Original-Host.The default is X-Original-Host.
OriginalProtoHeaderNameOriginalProtoHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XOriginalProtoHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalProtoHeaderName.

La valeur par défaut est X-Original-Proto.The default is X-Original-Proto.
RequireHeaderSymmetryRequireHeaderSymmetry Cette option impose que le nombre de valeurs d’en-tête soit synchronisé avec les ForwardedHeadersOptions.ForwardedHeaders en cours de traitement.Require the number of header values to be in sync between the ForwardedHeadersOptions.ForwardedHeaders being processed.

La valeur par défaut dans ASP.NET Core 1.x est true.The default in ASP.NET Core 1.x is true. La valeur par défaut dans ASP.NET Core versions 2.0 ou ultérieures est false.The default in ASP.NET Core 2.0 or later is false.
OptionOption DescriptionDescription
ForwardedForHeaderNameForwardedForHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XForwardedForHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedForHeaderName. Cette option est utilisée quand le proxy/redirecteur utilise un en-tête autre que l’en-tête X-Forwarded-For pour transférer les informations.This option is used when the proxy/forwarder doesn't use the X-Forwarded-For header but uses some other header to forward the information.

La valeur par défaut est X-Forwarded-For.The default is X-Forwarded-For.
ForwardedHeadersForwardedHeaders Identifie les redirecteurs à traiter.Identifies which forwarders should be processed. Consultez l’énumération ForwardedHeaders pour obtenir la liste des champs qui s’appliquent.See the ForwardedHeaders Enum for the list of fields that apply. En règle générale, les valeurs attribuées à cette propriété sont ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.Typical values assigned to this property are ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

La valeur par défaut est ForwardedHeaders.None.The default value is ForwardedHeaders.None.
ForwardedHostHeaderNameForwardedHostHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XForwardedHostHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedHostHeaderName. Cette option est utilisée quand le proxy/redirecteur utilise un en-tête autre que l’en-tête X-Forwarded-Host pour transférer les informations.This option is used when the proxy/forwarder doesn't use the X-Forwarded-Host header but uses some other header to forward the information.

La valeur par défaut est X-Forwarded-Host.The default is X-Forwarded-Host.
ForwardedProtoHeaderNameForwardedProtoHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XForwardedProtoHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedProtoHeaderName. Cette option est utilisée quand le proxy/redirecteur utilise un en-tête autre que l’en-tête X-Forwarded-Proto pour transférer les informations.This option is used when the proxy/forwarder doesn't use the X-Forwarded-Proto header but uses some other header to forward the information.

La valeur par défaut est X-Forwarded-Proto.The default is X-Forwarded-Proto.
ForwardLimitForwardLimit Limite le nombre d’entrées dans les en-têtes qui sont traités.Limits the number of entries in the headers that are processed. Définissez cette option sur null pour désactiver la limite, mais seulement si KnownProxies ou KnownNetworks sont configurés.Set to null to disable the limit, but this should only be done if KnownProxies or KnownNetworks are configured.

La valeur par défaut est 1.The default is 1.
KnownNetworksKnownNetworks Plages d’adresses des réseaux connus à partir desquels les en-têtes transférés peuvent être acceptés.Address ranges of known networks to accept forwarded headers from. Indiquez les plages d’adresses IP à l’aide de la notation CIDR (Classless Interdomain Routing).Provide IP ranges using Classless Interdomain Routing (CIDR) notation.

Si le serveur utilise des sockets en mode double, les adresses IPv4 sont fournies dans un format IPv6 (par exemple, 10.0.0.1 dans IPv4 représentée dans IPv6 en tant que ::ffff:10.0.0.1).If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1). Consultez IPAddress.MapToIPv6.See IPAddress.MapToIPv6. Déterminez si ce format est nécessaire en examinant HttpContext.Connection.RemoteIpAddress.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. Pour plus d’informations, consultez la section Configuration pour une adresse IPv4 représentée sous la forme d’une adresse IPv6.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

La valeur par défaut est un IList<IPNetwork> contenant une seule entrée pour IPAddress.Loopback.The default is an IList<IPNetwork> containing a single entry for IPAddress.Loopback.
KnownProxiesKnownProxies Adresses des proxy connus à partir desquels les en-têtes transférés peuvent être acceptés.Addresses of known proxies to accept forwarded headers from. Utilisez KnownProxies pour spécifier des correspondances d’adresse IP exactes.Use KnownProxies to specify exact IP address matches.

Si le serveur utilise des sockets en mode double, les adresses IPv4 sont fournies dans un format IPv6 (par exemple, 10.0.0.1 dans IPv4 représentée dans IPv6 en tant que ::ffff:10.0.0.1).If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1). Consultez IPAddress.MapToIPv6.See IPAddress.MapToIPv6. Déterminez si ce format est nécessaire en examinant HttpContext.Connection.RemoteIpAddress.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. Pour plus d’informations, consultez la section Configuration pour une adresse IPv4 représentée sous la forme d’une adresse IPv6.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

La valeur par défaut est un IList<IPAddress> contenant une seule entrée pour IPAddress.IPv6Loopback.The default is an IList<IPAddress> containing a single entry for IPAddress.IPv6Loopback.
OriginalForHeaderNameOriginalForHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XOriginalForHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalForHeaderName.

La valeur par défaut est X-Original-For.The default is X-Original-For.
OriginalHostHeaderNameOriginalHostHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XOriginalHostHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalHostHeaderName.

La valeur par défaut est X-Original-Host.The default is X-Original-Host.
OriginalProtoHeaderNameOriginalProtoHeaderName Utilisez l’en-tête spécifié par cette propriété à la place de celui spécifié par ForwardedHeadersDefaults.XOriginalProtoHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalProtoHeaderName.

La valeur par défaut est X-Original-Proto.The default is X-Original-Proto.
RequireHeaderSymmetryRequireHeaderSymmetry Cette option impose que le nombre de valeurs d’en-tête soit synchronisé avec les ForwardedHeadersOptions.ForwardedHeaders en cours de traitement.Require the number of header values to be in sync between the ForwardedHeadersOptions.ForwardedHeaders being processed.

La valeur par défaut dans ASP.NET Core 1.x est true.The default in ASP.NET Core 1.x is true. La valeur par défaut dans ASP.NET Core versions 2.0 ou ultérieures est false.The default in ASP.NET Core 2.0 or later is false.

Scénarios et cas d’usageScenarios and use cases

Quand il est impossible d’ajouter des en-têtes transférés et que toutes les requêtes sont sécuriséesWhen it isn't possible to add forwarded headers and all requests are secure

Dans certains cas, il peut être impossible d’ajouter des en-têtes transférés aux requêtes qui sont transmises par proxy à l’application.In some cases, it might not be possible to add forwarded headers to the requests proxied to the app. Si le proxy impose que toutes les requêtes externes publiques soient de type HTTPS, vous pouvez définir le schéma manuellement dans Startup.Configure avant d’utiliser tout type de middleware :If the proxy is enforcing that all public external requests are HTTPS, the scheme can be manually set in Startup.Configure before using any type of middleware:

app.Use((context, next) =>
{
    context.Request.Scheme = "https";
    return next();
});

Vous pouvez désactiver ce code avec une variable d’environnement ou un autre paramètre de configuration dans un environnement de préproduction ou de développement.This code can be disabled with an environment variable or other configuration setting in a development or staging environment.

Traiter la base du chemin et les proxys qui changent le chemin de la requêteDeal with path base and proxies that change the request path

Certains proxys passent le chemin tel quel, mais avec un chemin de base d’application qui doit être supprimé afin que le routage fonctionne correctement.Some proxies pass the path intact but with an app base path that should be removed so that routing works properly. Le middleware UsePathBaseExtensions.UsePathBase fractionne le chemin en HttpRequest.Path et le chemin de base d’application en HttpRequest.PathBase.UsePathBaseExtensions.UsePathBase middleware splits the path into HttpRequest.Path and the app base path into HttpRequest.PathBase.

Si /foo est le chemin de base d’application pour un chemin de proxy passé en tant que /foo/api/1, le middleware définit Request.PathBase sur /foo et Request.Path sur /api/1 avec la commande suivante :If /foo is the app base path for a proxy path passed as /foo/api/1, the middleware sets Request.PathBase to /foo and Request.Path to /api/1 with the following command:

app.UsePathBase("/foo");

Le chemin et la base du chemin d’origine sont réappliqués quand le middleware est rappelé dans l’ordre inverse.The original path and path base are reapplied when the middleware is called again in reverse. Pour plus d’informations sur le traitement des commandes de middleware, consultez le site Intergiciel (middleware) ASP.NET Core.For more information on middleware order processing, see Intergiciel (middleware) ASP.NET Core.

Si le proxy supprime le chemin (par exemple, en transférant /foo/api/1 vers /api/1), corrigez les redirections et les liens en définissant la propriété PathBase de la requête :If the proxy trims the path (for example, forwarding /foo/api/1 to /api/1), fix redirects and links by setting the request's PathBase property:

app.Use((context, next) =>
{
    context.Request.PathBase = new PathString("/foo");
    return next();
});

Si le proxy ajoute des données de chemin, ignorez la partie du chemin pour corriger les redirections et les liens en utilisant StartsWithSegments(PathString, PathString) et en définissant la propriété Path :If the proxy is adding path data, discard part of the path to fix redirects and links by using StartsWithSegments(PathString, PathString) and assigning to the Path property:

app.Use((context, next) =>
{
    if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
    {
        context.Request.Path = remainder;
    }

    return next();
});

Configuration d’un proxy qui utilise des noms d’en-têtes différentsConfiguration for a proxy that uses different header names

Si le proxy n’utilise pas des en-têtes nommés X-Forwarded-For et X-Forwarded-Proto pour transférer l’adresse/le port du proxy ainsi que les informations du schéma d’origine, définissez les options ForwardedForHeaderName et ForwardedProtoHeaderName pour faire correspondre les noms d’en-têtes utilisés par le proxy :If the proxy doesn't use headers named X-Forwarded-For and X-Forwarded-Proto to forward the proxy address/port and originating scheme information, set the ForwardedForHeaderName and ForwardedProtoHeaderName options to match the header names used by the proxy:

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedForHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-For_Header";
    options.ForwardedProtoHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-Proto_Header";
});

Configuration pour une adresse IPv4 représentée sous la forme d’une adresse IPv6Configuration for an IPv4 address represented as an IPv6 address

Si le serveur utilise des sockets en mode double, les adresses IPv4 sont fournies dans un format IPv6 (par exemple, 10.0.0.1 dans IPv4 représentée dans IPv6 en tant que ::ffff:10.0.0.1 ou ::ffff:a00:1).If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1 or ::ffff:a00:1). Consultez IPAddress.MapToIPv6.See IPAddress.MapToIPv6. Déterminez si ce format est nécessaire en examinant HttpContext.Connection.RemoteIpAddress.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress.

Dans l’exemple suivant, une adresse réseau qui fournit les en-têtes transférés est ajoutée à la liste KnownNetworks au format IPv6.In the following example, a network address that supplies forwarded headers is added to the KnownNetworks list in IPv6 format.

Adresse IPv4 : 10.11.12.1/8IPv4 address: 10.11.12.1/8

Adresse IPv6 convertie : ::ffff:10.11.12.1Converted IPv6 address: ::ffff:10.11.12.1
Longueur de préfixe converti : 104Converted prefix length: 104

Vous pouvez également fournir l’adresse au format hexadécimal (10.11.12.1 représenté dans IPv6 en tant que ::ffff:0a0b:0c01).You can also supply the address in hexadecimal format (10.11.12.1 represented in IPv6 as ::ffff:0a0b:0c01). Lors de la conversion d’une adresse IPv4 vers IPv6, ajoutez 96 à la longueur du préfixe CIDR (8 dans l’exemple) pour prendre en compte le préfixe IPv6 ::ffff: supplémentaire (8 + 96 = 104).When converting an IPv4 address to IPv6, add 96 to the CIDR Prefix Length (8 in the example) to account for the additional ::ffff: IPv6 prefix (8 + 96 = 104).

// To access IPNetwork and IPAddress, add the following namespaces:
// using using System.Net;
// using Microsoft.AspNetCore.HttpOverrides;
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownNetworks.Add(new IPNetwork(
        IPAddress.Parse("::ffff:10.11.12.1"), 104));
});

Résoudre les problèmesTroubleshoot

Quand des en-têtes ne sont pas transférés comme prévu, activez la journalisation.When headers aren't forwarded as expected, enable logging. Si les journaux ne fournissent pas suffisamment d’informations pour résoudre le problème, énumérez les en-têtes de requête reçus par le serveur.If the logs don't provide sufficient information to troubleshoot the problem, enumerate the request headers received by the server. Utilisez le middleware inclus pour écrire les en-têtes de requête dans une réponse d’application, ou consignez les en-têtes dans le fichier journal.Use inline middleware to write request headers to an app response or log the headers. Placez l’un des exemples de code suivants immédiatement après l’appel à UseForwardedHeaders dans Startup.Configure.Place either of the following code examples immediately after the call to UseForwardedHeaders in Startup.Configure.

Pour écrire les en-têtes dans la réponse de l’application, utilisez le middleware inclus de terminal suivant :To write the headers to the app's response, use the following terminal inline middleware:

app.Run(async (context) =>
{
    context.Response.ContentType = "text/plain";

    // Request method, scheme, and path
    await context.Response.WriteAsync(
        $"Request Method: {context.Request.Method}{Environment.NewLine}");
    await context.Response.WriteAsync(
        $"Request Scheme: {context.Request.Scheme}{Environment.NewLine}");
    await context.Response.WriteAsync(
        $"Request Path: {context.Request.Path}{Environment.NewLine}");

    // Headers
    await context.Response.WriteAsync($"Request Headers:{Environment.NewLine}");

    foreach (var header in context.Request.Headers)
    {
        await context.Response.WriteAsync($"{header.Key}: " +
            $"{header.Value}{Environment.NewLine}");
    }

    await context.Response.WriteAsync(Environment.NewLine);

    // Connection: RemoteIp
    await context.Response.WriteAsync(
        $"Request RemoteIp: {context.Connection.RemoteIpAddress}");
});

Vous pouvez également écrire dans les journaux au lieu d’utiliser le corps de réponse en utilisant le middleware inclus suivant.You can also write to logs instead of the response body by using the following inline middleware. De cette façon, le site fonctionne normalement pendant le débogage.This allows the site to function normally while debugging.

var logger = _loggerFactory.CreateLogger<Startup>();

app.Use(async (context, next) =>
{
    // Request method, scheme, and path
    logger.LogDebug("Request Method: {METHOD}", context.Request.Method);
    logger.LogDebug("Request Scheme: {SCHEME}", context.Request.Scheme);
    logger.LogDebug("Request Path: {PATH}", context.Request.Path);

    // Headers
    foreach (var header in context.Request.Headers)
    {
        logger.LogDebug("Header: {KEY}: {VALUE}", header.Key, header.Value);
    }

    // Connection: RemoteIp
    logger.LogDebug("Request RemoteIp: {REMOTE_IP_ADDRESS}", 
        context.Connection.RemoteIpAddress);

    await next();
});

Lors du traitement, les valeurs X-Forwarded-{For|Proto|Host} sont déplacées vers X-Original-{For|Proto|Host}.When processed, X-Forwarded-{For|Proto|Host} values are moved to X-Original-{For|Proto|Host}. S’il existe plusieurs valeurs dans un en-tête donné, notez que le middleware des en-têtes transférés traite les en-têtes dans l’ordre inverse de droite à gauche.If there are multiple values in a given header, note Forwarded Headers Middleware processes headers in reverse order from right to left. La valeur par défaut de ForwardLimit est 1 (un) si bien que la valeur la plus à droite dans les en-têtes est traitée, sauf si la valeur de ForwardLimit est augmentée.The default ForwardLimit is 1 (one), so only the rightmost value from the headers is processed unless the value of ForwardLimit is increased.

L’adresse IP distante d’origine de la requête doit correspondre à une entrée dans les listes KnownProxies ou KnownNetworks pour que les en-têtes transférés soient traités.The request's original remote IP must match an entry in the KnownProxies or KnownNetworks lists before forwarded headers are processed. L’usurpation des en-têtes s’en trouve limitée, car les redirecteurs émanant de proxys non approuvés ne sont pas acceptés.This limits header spoofing by not accepting forwarders from untrusted proxies. Lorsqu’un proxy inconnu est détecté, la journalisation indique l’adresse du proxy :When an unknown proxy is detected, logging indicates the address of the proxy:

September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321

Dans l’exemple précédent, 10.0.0.100 est un serveur proxy.In the preceding example, 10.0.0.100 is a proxy server. Si le serveur est un proxy approuvé, ajoutez l’adresse IP du serveur à la liste KnownProxies (ou ajoutez un réseau approuvé à la liste KnownNetworks) dans Startup.ConfigureServices.If the server is a trusted proxy, add the server's IP address to KnownProxies (or add a trusted network to KnownNetworks) in Startup.ConfigureServices. Pour plus d’informations, consultez la section Options du middleware des en-têtes transférés.For more information, see the Forwarded Headers Middleware options section.

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

Important

Autorisez uniquement des réseaux et des proxies approuvés pour transférer des en-têtes.Only allow trusted proxies and networks to forward headers. Sinon, des attaques d’usurpation d’adresse IP sont possibles.Otherwise, IP spoofing attacks are possible.

Ressources supplémentairesAdditional resources