Configurare ASP.NET Core per l'uso di server proxy e servizi di bilanciamento del caricoConfigure ASP.NET Core to work with proxy servers and load balancers

Di Luke Latham e Chris RossBy Luke Latham and Chris Ross

Nella configurazione consigliata per ASP.NET Core, l'app è ospitata mediante IIS e il modulo ASP.NET Core, Nginx o Apache.In the recommended configuration for ASP.NET Core, the app is hosted using IIS/ASP.NET Core Module, Nginx, or Apache. Server proxy, servizi di bilanciamento del carico e altre appliance di rete spesso nascondono informazioni sulla richiesta prima che questa raggiunga l'app:Proxy servers, load balancers, and other network appliances often obscure information about the request before it reaches the app:

  • Quando le richieste HTTPS vengono trasmesse tramite proxy su HTTP, lo schema originale (HTTPS) viene perso e deve essere inoltrato in un'intestazione.When HTTPS requests are proxied over HTTP, the original scheme (HTTPS) is lost and must be forwarded in a header.
  • Poiché un'app riceve una richiesta dal proxy e non dall'effettiva origine su Internet o nella rete aziendale, anche l'indirizzo IP di origine del client deve essere inoltrato in un'intestazione.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.

Queste informazioni potrebbero essere importanti per l'elaborazione delle richieste, ad esempio per i reindirizzamenti, l'autenticazione, la generazione di collegamenti, la valutazione dei criteri e la georilevazione dei client.This information may be important in request processing, for example in redirects, authentication, link generation, policy evaluation, and client geolocation.

Intestazioni inoltrateForwarded headers

Per convenzione, i proxy inoltrano le informazioni nelle intestazioni HTTP.By convention, proxies forward information in HTTP headers.

HeaderHeader DESCRIZIONEDescription
X-Forwarded-ForX-Forwarded-For Contiene informazioni sul client che ha avviato la richiesta e sui proxy successivi in una catena di proxy.Holds information about the client that initiated the request and subsequent proxies in a chain of proxies. Questo parametro può contenere indirizzi IP (e, facoltativamente, numeri di porta).This parameter may contain IP addresses (and, optionally, port numbers). In una catena di server proxy, il primo parametro indica il client in cui è stata eseguita inizialmente la richiesta.In a chain of proxy servers, the first parameter indicates the client where the request was first made. Seguono gli identificatori dei proxy successivi.Subsequent proxy identifiers follow. L'ultimo proxy della catena non è incluso nell'elenco dei parametri.The last proxy in the chain isn't in the list of parameters. L'indirizzo IP dell'ultimo proxy e, facoltativamente, un numero di porta sono disponibili come indirizzo IP remoto a livello di trasporto.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 Il valore dello schema di origine (HTTP/HTTPS).The value of the originating scheme (HTTP/HTTPS). Il valore può essere anche un elenco di schemi, se la richiesta ha attraversato più proxy.The value may also be a list of schemes if the request has traversed multiple proxies.
X-Forwarded-HostX-Forwarded-Host Il valore originale del campo dell'intestazione host.The original value of the Host header field. I proxy in genere non modificano l'intestazione host.Usually, proxies don't modify the Host header. Vedere l'avviso di sicurezza Microsoft CVE-2018-0787 per informazioni su una vulnerabilità di elevazione dei privilegi che interessa i sistemi in cui il proxy non convalida o limita le intestazioni host a valori di riferimento noti.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.

Il middleware delle intestazioni inoltrate, dal pacchetto Microsoft.AspNetCore.HttpOverrides, legge le intestazioni e compila i campi associati in HttpContext.The Forwarded Headers Middleware, from the Microsoft.AspNetCore.HttpOverrides package, reads these headers and fills in the associated fields on HttpContext.

Il middleware aggiorna:The middleware updates:

È possibile configurare le impostazioni predefinite del middleware delle intestazioni inoltrate.Forwarded Headers Middleware default settings can be configured. Le impostazioni predefinite sono le seguenti:The default settings are:

  • È presente un solo proxy tra l'app e l'origine delle richieste.There is only one proxy between the app and the source of the requests.
  • Sono configurati indirizzi di loopback solo per reti e proxy noti.Only loopback addresses are configured for known proxies and known networks.
  • Le intestazioni inoltrate sono denominate X-Forwarded-For e X-Forwarded-Proto.The forwarded headers are named X-Forwarded-For and X-Forwarded-Proto.

Non tutte le appliance di rete aggiungono le intestazioni X-Forwarded-For e X-Forwarded-Proto senza alcuna configurazione aggiuntiva.Not all network appliances add the X-Forwarded-For and X-Forwarded-Proto headers without additional configuration. Se le richieste trasmesse tramite proxy non contengono queste intestazioni quando raggiungono l'app, fare riferimento alle indicazioni del produttore dell'appliance.Consult your appliance manufacturer's guidance if proxied requests don't contain these headers when they reach the app. Se l'appliance usa nomi di intestazione diversi da X-Forwarded-For e X-Forwarded-Proto, impostare le opzioni ForwardedForHeaderName e ForwardedProtoHeaderName in modo che corrispondano ai nomi di intestazione usati dall'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. Per altre informazioni, vedere Opzioni del middleware delle intestazioni inoltrate e Configurazione per un proxy che usa nomi di intestazione diversi.For more information, see Forwarded Headers Middleware options and Configuration for a proxy that uses different header names.

IIS/IIS Express e modulo Core ASP.NETIIS/IIS Express and ASP.NET Core Module

Il middleware delle intestazioni inoltrate è abilitato per impostazione predefinita dal middleware di integrazione IIS quando l'app è ospitata out-of-process dietro IIS e il modulo ASP.NET Core.Forwarded Headers Middleware is enabled by default by IIS Integration Middleware when the app is hosted out-of-process behind IIS and the ASP.NET Core Module. Il middleware delle intestazioni inoltrate viene attivato per l'esecuzione prima nella pipeline del middleware con una configurazione con restrizioni specifica per il modulo ASP.NET Core per motivi di attendibilità delle intestazioni inoltrate, ad esempio lo spoofing degli indirizzi 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). Il middleware è configurato per inoltrare le intestazioni X-Forwarded-For e X-Forwarded-Proto ed è limitato a un singolo proxy localhost.The middleware is configured to forward the X-Forwarded-For and X-Forwarded-Proto headers and is restricted to a single localhost proxy. Se è richiesta una configurazione aggiuntiva, vedere Opzioni del middleware delle intestazioni inoltrate.If additional configuration is required, see the Forwarded Headers Middleware options.

Altri scenari con server proxy e servizi di bilanciamento del caricoOther proxy server and load balancer scenarios

Se non si usa il middleware di integrazione IIS per l'hosting out-of-process, il middleware delle intestazioni inoltrate non è abilitato per impostazione predefinita.Outside of using IIS Integration when hosting out-of-process, Forwarded Headers Middleware isn't enabled by default. Il middleware delle intestazioni inoltrate deve essere abilitato per consentire a un'app di inoltrare le intestazioni inoltrate del processo con UseForwardedHeaders.Forwarded Headers Middleware must be enabled for an app to process forwarded headers with UseForwardedHeaders. Dopo aver abilitato il middleware, se non sono specificate opzioni ForwardedHeadersOptions per il middleware, le intestazioni ForwardedHeadersOptions.ForwardedHeaders predefinite sono ForwardedHeaders.None.After enabling the middleware if no ForwardedHeadersOptions are specified to the middleware, the default ForwardedHeadersOptions.ForwardedHeaders are ForwardedHeaders.None.

Configurare il middleware con ForwardedHeadersOptions per l'inoltro delle intestazioni X-Forwarded-For e X-Forwarded-Proto in Startup.ConfigureServices.Configure the middleware with ForwardedHeadersOptions to forward the X-Forwarded-For and X-Forwarded-Proto headers in Startup.ConfigureServices. Richiamare il metodo UseForwardedHeaders in Startup.Configure prima di chiamare altro middleware: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();
}

Nota

Se non vengono specificate ForwardedHeadersOptions in Startup.ConfigureServices o direttamente nel metodo di estensione con UseForwardedHeaders, le intestazioni predefinite da inoltrare sono ForwardedHeaders.None.If no ForwardedHeadersOptions are specified in Startup.ConfigureServices or directly to the extension method with UseForwardedHeaders, the default headers to forward are ForwardedHeaders.None. La proprietà ForwardedHeaders deve essere configurata con le intestazioni da inoltrare.The ForwardedHeaders property must be configured with the headers to forward.

Configurazione NginxNginx configuration

Per inoltrare le intestazioni X-Forwarded-For e X-Forwarded-Proto, vedere Hosting di ASP.NET Core in Linux con Nginx.To forward the X-Forwarded-For and X-Forwarded-Proto headers, see Hosting di ASP.NET Core in Linux con Nginx. Per altre informazioni, vedere NGINX: Using the Forwarded header (NGINX: Uso dell'intestazione Forwarded).For more information, see NGINX: Using the Forwarded header.

Configurazione ApacheApache configuration

X-Forwarded-For viene aggiunta automaticamente. Vedere Apache Module mod_proxy: Reverse Proxy Request Headers (Modulo Apache mod_proxy: Intestazioni delle richieste del proxy inverso).X-Forwarded-For is added automatically (see Apache Module mod_proxy: Reverse Proxy Request Headers). Per informazioni su come inoltrare l'intestazione X-Forwarded-Proto, vedere Hosting di ASP.NET Core in Linux con Apache.For information on how to forward the X-Forwarded-Proto header, see Hosting di ASP.NET Core in Linux con Apache.

Opzioni del middleware delle intestazioni inoltrateForwarded Headers Middleware options

ForwardedHeadersOptions controllano il comportamento del middleware delle intestazioni inoltrate.ForwardedHeadersOptions control the behavior of the Forwarded Headers Middleware. L'esempio seguente modifica i valori predefiniti:The following example changes the default values:

  • Limitare il numero di voci nelle intestazioni inoltrate a 2.Limit the number of entries in the forwarded headers to 2.
  • Aggiungere un indirizzo proxy noto di 127.0.10.1.Add a known proxy address of 127.0.10.1.
  • Modificare il nome dell'intestazione inoltrata dal nome predefinito X-Forwarded-For a 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";
});
OpzioneOption DESCRIZIONEDescription
AllowedHosts Limita gli host mediante l'intestazione X-Forwarded-Host ai valori specificati.Restricts hosts by the X-Forwarded-Host header to the values provided.
  • I valori vengono confrontati tramite ordinal-ignore-case.Values are compared using ordinal-ignore-case.
  • I numeri di porta devono essere esclusi.Port numbers must be excluded.
  • Se l'elenco è vuoto, sono consentiti tutti gli host.If the list is empty, all hosts are allowed.
  • Un carattere jolly di primo livello * consente tutti gli host non vuoti.A top-level wildcard * allows all non-empty hosts.
  • I caratteri jolly per i sottodomini sono consentiti, ma non corrispondono al dominio radice.Subdomain wildcards are permitted but don't match the root domain. Ad esempio, *.contoso.com corrisponde al sottodominio foo.contoso.com, ma non al dominio radice contoso.com.For example, *.contoso.com matches the subdomain foo.contoso.com but not the root domain contoso.com.
  • I nomi host Unicode sono consentiti ma vengono convertiti in Punycode per la corrispondenza.Unicode host names are allowed but are converted to Punycode for matching.
  • Gli indirizzi IPv6 devono includere le parentesi quadre di delimitazione ed essere in formato convenzionale, ad esempio [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]). Per gli indirizzi IPv6 non viene applicata la distinzione tra maiuscole e minuscole per la verifica dell'uguaglianza logica tra i diversi formati e non viene eseguita alcuna canonizzazione.IPv6 addresses aren't special-cased to check for logical equality between different formats, and no canonicalization is performed.
  • La mancata limitazione degli host consentiti potrebbe permettere a un utente malintenzionato di eseguire lo spoofing dei collegamenti generati dal servizio.Failure to restrict the allowed hosts may allow an attacker to spoof links generated by the service.
Il valore predefinito è un insieme IList<string> vuoto.The default value is an empty IList<string>.
ForwardedForHeaderName Usare l'intestazione specificata da questa proprietà anziché quella specificata da ForwardedHeadersDefaults.XForwardedForHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedForHeaderName. Questa opzione viene usata quando il proxy o il server d'inoltro non usa l'intestazione X-Forwarded-For ma usa un'altra intestazione per inoltrare le informazioni.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.

Il valore predefinito è X-Forwarded-For.The default is X-Forwarded-For.
ForwardedHeaders Identifica i server d'inoltro che devono essere elaborati.Identifies which forwarders should be processed. Vedere ForwardedHeaders Enum (Enumerazione ForwardedHeaders) per l'elenco dei campi applicabili.See the ForwardedHeaders Enum for the list of fields that apply. I valori tipici assegnati a questa proprietà sono 'ForwardedHeaders.XForwardedForTypical values assigned to this property are `ForwardedHeaders.XForwardedFor ForwardedHeaders.XForwardedProto'.ForwardedHeaders.XForwardedProto`.

Il valore predefinito è ForwardedHeaders.None.The default value is ForwardedHeaders.None.
ForwardedHostHeaderName Usare l'intestazione specificata da questa proprietà anziché quella specificata da ForwardedHeadersDefaults.XForwardedHostHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedHostHeaderName. Questa opzione viene usata quando il proxy o il server d'inoltro non usa l'intestazione X-Forwarded-Host ma usa un'altra intestazione per inoltrare le informazioni.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.

Il valore predefinito è X-Forwarded-Host.The default is X-Forwarded-Host.
ForwardedProtoHeaderName Usare l'intestazione specificata da questa proprietà anziché quella specificata da ForwardedHeadersDefaults.XForwardedProtoHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedProtoHeaderName. Questa opzione viene usata quando il proxy o il server d'inoltro non usa l'intestazione X-Forwarded-Proto ma usa un'altra intestazione per inoltrare le informazioni.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.

Il valore predefinito è X-Forwarded-Proto.The default is X-Forwarded-Proto.
ForwardLimit Limita il numero di voci nelle intestazioni elaborate.Limits the number of entries in the headers that are processed. Impostare su null per disabilitare il limite, ma solo se è configurato KnownProxies o KnownNetworks.Set to null to disable the limit, but this should only be done if KnownProxies or KnownNetworks are configured. L'impostazione di un valore non null è una precauzione (ma non una garanzia) per proteggersi da proxy non configurati correttamente e richieste dannose provenienti da canali laterali in rete.Setting a non-null value is a precaution (but not a guarantee) to guard against misconfigured proxies and malicious requests arriving from side-channels on the network.

Il middleware delle intestazioni inoltrate elabora le intestazioni in ordine inverso da destra a sinistra.Forwarded Headers Middleware processes headers in reverse order from right to left. Se viene usato il valore predefinito (1), viene elaborato solo il valore più a destra delle intestazioni, a meno che non venga aumentato il valore di ForwardLimit.If the default value (1) is used, only the rightmost value from the headers is processed unless the value of ForwardLimit is increased.

Il valore predefinito è 1.The default is 1.
KnownNetworks Intervalli di indirizzi delle reti note da cui accettare le intestazioni inoltrate.Address ranges of known networks to accept forwarded headers from. Specificare gli intervalli IP usando la notazione CIDR (Classless Interdomain Routing).Provide IP ranges using Classless Interdomain Routing (CIDR) notation.

Se il server usa socket dual mode, gli indirizzi IPv4 vengono forniti in un formato IPv6 (ad esempio, 10.0.0.1 in IPv4 rappresentato in IPv6 come ::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). Vedere IPAddress.MapToIPv6.See IPAddress.MapToIPv6. Determinare se questo formato è richiesto esaminando HttpContext.Connection.RemoteIpAddress.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. Per altre informazioni, vedere la sezione Configurazione per un indirizzo IPv4 rappresentato come indirizzo IPv6.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

Il valore predefinito è un oggetto IList<IPNetwork> contenente una singola voce per IPAddress.Loopback.The default is an IList<IPNetwork> containing a single entry for IPAddress.Loopback.
KnownProxies Indirizzi dei proxy noti da cui accettare le intestazioni inoltrate.Addresses of known proxies to accept forwarded headers from. Usare KnownProxies per specificare le corrispondenze esatte degli indirizzi IP.Use KnownProxies to specify exact IP address matches.

Se il server usa socket dual mode, gli indirizzi IPv4 vengono forniti in un formato IPv6 (ad esempio, 10.0.0.1 in IPv4 rappresentato in IPv6 come ::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). Vedere IPAddress.MapToIPv6.See IPAddress.MapToIPv6. Determinare se questo formato è richiesto esaminando HttpContext.Connection.RemoteIpAddress.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. Per altre informazioni, vedere la sezione Configurazione per un indirizzo IPv4 rappresentato come indirizzo IPv6.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

Il valore predefinito è un oggetto IList<IPAddress> contenente una singola voce per IPAddress.IPv6Loopback.The default is an IList<IPAddress> containing a single entry for IPAddress.IPv6Loopback.
OriginalForHeaderName Usare l'intestazione specificata da questa proprietà anziché quella specificata da ForwardedHeadersDefaults.XOriginalForHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalForHeaderName.

Il valore predefinito è X-Original-For.The default is X-Original-For.
OriginalHostHeaderName Usare l'intestazione specificata da questa proprietà anziché quella specificata da ForwardedHeadersDefaults.XOriginalHostHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalHostHeaderName.

Il valore predefinito è X-Original-Host.The default is X-Original-Host.
OriginalProtoHeaderName Usare l'intestazione specificata da questa proprietà anziché quella specificata da ForwardedHeadersDefaults.XOriginalProtoHeaderName.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalProtoHeaderName.

Il valore predefinito è X-Original-Proto.The default is X-Original-Proto.
RequireHeaderSymmetry Richiedere il numero di valori di intestazione da sincronizzare tra le intestazioni ForwardedHeadersOptions.ForwardedHeaders in fase di elaborazione.Require the number of header values to be in sync between the ForwardedHeadersOptions.ForwardedHeaders being processed.

Il valore predefinito in ASP.NET Core 1.x è true.The default in ASP.NET Core 1.x is true. Il valore predefinito in ASP.NET Core 2.0 o versione successiva è false.The default in ASP.NET Core 2.0 or later is false.

Scenari e casi d'usoScenarios and use cases

Quando non è possibile aggiungere le intestazioni inoltrate e tutte le richieste sono sicureWhen it isn't possible to add forwarded headers and all requests are secure

In alcuni casi, potrebbe non essere possibile aggiungere le intestazioni inoltrate alle richieste trasmesse tramite proxy all'app.In some cases, it might not be possible to add forwarded headers to the requests proxied to the app. Se il proxy impone che tutte le richieste esterne pubbliche siano HTTPS, lo schema può essere impostato manualmente in Startup.Configure prima di usare qualsiasi tipo di 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();
});

Questo codice può essere disabilitato tramite una variabile di ambiente o un'altra impostazione di configurazione in un ambiente di sviluppo o di gestione temporanea.This code can be disabled with an environment variable or other configuration setting in a development or staging environment.

Gestire la base del percorso e i proxy che modificano il percorso della richiestaDeal with path base and proxies that change the request path

Alcuni proxy passano il percorso senza modifiche, ma con un percorso di base dell'app che deve essere rimosso per consentire il corretto funzionamento del routing.Some proxies pass the path intact but with an app base path that should be removed so that routing works properly. Il middleware UsePathBaseExtensions.UsePathBase suddivide il percorso in HttpRequest.Path e il percorso di base dell'app in HttpRequest.PathBase.UsePathBaseExtensions.UsePathBase middleware splits the path into HttpRequest.Path and the app base path into HttpRequest.PathBase.

Se /foo è il percorso di base dell'app per un percorso proxy passato come /foo/api/1, il middleware imposta Request.PathBase su /foo e Request.Path su /api/1 con il comando seguente: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");

Il percorso originale e la base del percorso vengono riapplicati quando il middleware viene chiamato nuovamente in direzione inversa.The original path and path base are reapplied when the middleware is called again in reverse. Per altre informazioni dell'elaborazione degli ordini del middleware, vedere Middleware di ASP.NET Core.For more information on middleware order processing, see Middleware di ASP.NET Core.

Se il proxy taglia il percorso (ad esempio, inoltrando /foo/api/1 a /api/1), correggere i reindirizzamenti e i collegamenti impostando la proprietà PathBase della richiesta: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();
});

Se il proxy aggiunge i dati del percorso, eliminare parte del percorso per correggere i reindirizzamenti e i collegamenti usando StartsWithSegments ed eseguendo l'assegnazione alla proprietà Path:If the proxy is adding path data, discard part of the path to fix redirects and links by using StartsWithSegments 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();
});

Configurazione per un proxy che usa nomi di intestazione diversiConfiguration for a proxy that uses different header names

Se il proxy non usa intestazioni denominate X-Forwarded-For e X-Forwarded-Proto per inoltrare l'indirizzo proxy o la porta e le informazioni dello scherma originali, impostare le opzioni ForwardedForHeaderName e ForwardedProtoHeaderName in modo che corrispondano ai nomi di intestazione usati dal 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";
});

Configurazione per un indirizzo IPv4 rappresentato come indirizzo IPv6Configuration for an IPv4 address represented as an IPv6 address

Se il server usa socket dual mode, gli indirizzi IPv4 vengono forniti in un formato IPv6 (ad esempio, 10.0.0.1 in IPv4 rappresentato in IPv6 come ::ffff:10.0.0.1 o ::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). Vedere IPAddress.MapToIPv6.See IPAddress.MapToIPv6. Determinare se questo formato è richiesto esaminando HttpContext.Connection.RemoteIpAddress.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress.

Nell'esempio seguente un indirizzo di rete che fornisce intestazioni inoltrate viene aggiunto all'elenco KnownNetworks in formato IPv6.In the following example, a network address that supplies forwarded headers is added to the KnownNetworks list in IPv6 format.

Indirizzo IPv4: 10.11.12.1/8IPv4 address: 10.11.12.1/8

Indirizzo IPv6 convertito: ::ffff:10.11.12.1Converted IPv6 address: ::ffff:10.11.12.1
Lunghezza del prefisso convertito: 104Converted prefix length: 104

È anche possibile specificare l'indirizzo in formato esadecimale (10.11.12.1 rappresentato in IPv6 come ::ffff:0a0b:0c01).You can also supply the address in hexadecimal format (10.11.12.1 represented in IPv6 as ::ffff:0a0b:0c01). Durante la conversione di un indirizzo IPv4 in IPv6, aggiungere 96 alla lunghezza del prefisso CIDR (8 nell'esempio) per tenere conto del prefisso IPv6 aggiuntivo ::ffff: (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));
});

Inoltrare lo schema per Linux e proxy inversi non IISForward the scheme for Linux and non-IIS reverse proxies

Con le app che chiamano UseHttpsRedirection e UseHsts il sito si ritrova in un ciclo infinito se distribuito in un servizio app Linux di Azure, in una macchina virtuale Linux di Azure o dietro eventuali altri proxy inversi diversi da IIS.Apps that call UseHttpsRedirection and UseHsts put a site into an infinite loop if deployed to an Azure Linux App Service, Azure Linux virtual machine (VM), or behind any other reverse proxy besides IIS. TLS viene terminato dal proxy inverso e Kestrel non viene a conoscenza dello schema di richiesta corretto.TLS is terminated by the reverse proxy, and Kestrel isn't made aware of the correct request scheme. Si verificano errori anche per OAuth e OIDC in questa configurazione perché generano reindirizzamenti non corretti.OAuth and OIDC also fail in this configuration because they generate incorrect redirects. UseIISIntegration aggiunge e configura il middleware delle intestazioni inoltrate in caso di esecuzione dietro IIS, ma non esiste alcuna configurazione automatica corrispondente per Linux (integrazione di Apache o Nginx).UseIISIntegration adds and configures Forwarded Headers Middleware when running behind IIS, but there's no matching automatic configuration for Linux (Apache or Nginx integration).

Per inoltrare lo schema dal proxy in scenari non IIS, aggiungere e configurare il middleware delle intestazioni inoltrate.To forward the scheme from the proxy in non-IIS scenarios, add and configure Forwarded Headers Middleware. In Startup.ConfigureServices usare il codice seguente:In Startup.ConfigureServices, use the following code:

// using Microsoft.AspNetCore.HttpOverrides;

if (string.Equals(
    Environment.GetEnvironmentVariable("ASPNETCORE_FORWARDEDHEADERS_ENABLED"), 
    "true", StringComparison.OrdinalIgnoreCase))
{
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | 
            ForwardedHeaders.XForwardedProto;
        // Only loopback proxies are allowed by default.
        // Clear that restriction because forwarders are enabled by explicit 
        // configuration.
        options.KnownNetworks.Clear();
        options.KnownProxies.Clear();
    });
}

Risolvere i problemiTroubleshoot

Quando le intestazioni non vengono inoltrate come previsto, abilitare la registrazione.When headers aren't forwarded as expected, enable logging. Se i log non forniscono informazioni sufficienti per risolvere il problema, enumerare le intestazioni delle richieste ricevute dal server.If the logs don't provide sufficient information to troubleshoot the problem, enumerate the request headers received by the server. Usare il middleware inline per scrivere le intestazioni di richiesta in una risposta dell'app o per registrare le intestazioni.Use inline middleware to write request headers to an app response or log the headers.

Per scrivere le intestazioni nella risposta dell'app, aggiungere il middleware inline di terminale seguente immediatamente dopo la chiamata a UseForwardedHeaders in Startup.Configure:To write the headers to the app's response, place the following terminal inline middleware immediately after the call to UseForwardedHeaders in Startup.Configure:

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}");
});

È possibile scrivere nei log invece che nel corpo della risposta.You can write to logs instead of the response body. La scrittura nei log permette il normale funzionamento del sito durante il debug.Writing to logs allows the site to function normally while debugging.

Per scrivere nei log invece che nel corpo della risposta:To write logs rather than to the response body:

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();
});

Durante l'elaborazione, i valori di X-Forwarded-{For|Proto|Host} vengono spostati in X-Original-{For|Proto|Host}.When processed, X-Forwarded-{For|Proto|Host} values are moved to X-Original-{For|Proto|Host}. Se sono presenti più valori in una determinata intestazione, il middleware delle intestazioni inoltrate elabora le intestazioni in ordine inverso da destra a sinistra.If there are multiple values in a given header, Forwarded Headers Middleware processes headers in reverse order from right to left. Il valore predefinito di ForwardLimit è 1 (uno) e, pertanto, viene elaborato solo il valore più a destra delle intestazioni, a meno che non venga aumentato il valore di ForwardLimit.The default ForwardLimit is 1 (one), so only the rightmost value from the headers is processed unless the value of ForwardLimit is increased.

L'indirizzo IP remoto originale della richiesta deve corrispondere a una voce negli elenchi KnownProxies o KnownNetworks prima dell'elaborazione delle intestazioni inoltrate.The request's original remote IP must match an entry in the KnownProxies or KnownNetworks lists before forwarded headers are processed. Questo riduce lo spoofing delle intestazioni, non accettando server di inoltro da proxy non attendibili.This limits header spoofing by not accepting forwarders from untrusted proxies. Quando viene rilevato un proxy sconosciuto, la registrazione indica l'indirizzo del 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

Nell'esempio precedente, 10.0.0.100 è un server proxy.In the preceding example, 10.0.0.100 is a proxy server. Se il server è un proxy attendibile, aggiungere l'indirizzo IP del server a KnownProxies (o aggiungere una rete attendibile a KnownNetworks) in 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. Per altre informazioni, vedere la sezione Opzioni del middleware delle intestazioni inoltrate.For more information, see the Forwarded Headers Middleware options section.

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

Importante

Consentire solo a reti e proxy attendibili di inoltrare le intestazioni.Only allow trusted proxies and networks to forward headers. In caso contrario, possono verificarsi attacchi di spoofing degli indirizzi IP.Otherwise, IP spoofing attacks are possible.

Inoltro di certificatiCertificate forwarding

In AzureOn Azure

Vedere la documentazione di Azure per configurare le app Web di Azure.See the Azure documentation to configure Azure Web Apps. Nel metodo Startup.Configure dell'app aggiungere il codice seguente prima della chiamata a app.UseAuthentication();:In your app's Startup.Configure method, add the following code before the call to app.UseAuthentication();:

app.UseCertificateForwarding();

Sarà anche necessario configurare il middleware di inoltro dei certificati per specificare il nome dell'intestazione usata da Azure.You'll also need to configure the Certificate Forwarding middleware to specify the header name that Azure uses. Nel metodo Startup.ConfigureServices dell'app aggiungere il codice seguente per configurare l'intestazione da cui il middleware crea un certificato:In your app's Startup.ConfigureServices method, add the following code to configure the header from which the middleware builds a certificate:

services.AddCertificateForwarding(options =>
    options.CertificateHeader = "X-ARR-ClientCert");

Con altri proxy WebWith other web proxies

Se si usa un proxy che non sia IIS o Application Request Routing per app Web di Azure, configurare il proxy per inoltrare il certificato ricevuto in un'intestazione HTTP.If you're using a proxy that isn't IIS or Azure's Web Apps Application Request Routing, configure your proxy to forward the certificate it received in an HTTP header. Nel metodo Startup.Configure dell'app aggiungere il codice seguente prima della chiamata a app.UseAuthentication();:In your app's Startup.Configure method, add the following code before the call to app.UseAuthentication();:

app.UseCertificateForwarding();

Sarà anche necessario configurare il middleware di inoltro dei certificati per specificare il nome dell'intestazione.You'll also need to configure the Certificate Forwarding middleware to specify the header name. Nel metodo Startup.ConfigureServices dell'app aggiungere il codice seguente per configurare l'intestazione da cui il middleware crea un certificato:In your app's Startup.ConfigureServices method, add the following code to configure the header from which the middleware builds a certificate:

services.AddCertificateForwarding(options =>
    options.CertificateHeader = "YOUR_CERTIFICATE_HEADER_NAME");

Infine, se il proxy esegue operazioni diverse dalla codifica base64 del certificato (come nel caso di Nginx), impostare l'opzione HeaderConverter.Finally, if the proxy is doing something other than base64 encoding the certificate (as is the case with Nginx), set the HeaderConverter option. Si consideri l'esempio seguente in Startup.ConfigureServices:Consider the following example in Startup.ConfigureServices:

services.AddCertificateForwarding(options =>
{
    options.CertificateHeader = "YOUR_CUSTOM_HEADER_NAME";
    options.HeaderConverter = (headerValue) => 
    {
        var clientCertificate = 
           /* some conversion logic to create an X509Certificate2 */
        return clientCertificate;
    }
});

Risorse aggiuntiveAdditional resources