Konfigurace ASP.NET Core pro práci s proxy servery a nástroji pro vyrovnávání zatížení

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 10 tohoto článku.

Varování

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete ve verzi .NET 10 tohoto článku.

Autor: Chris Ross

V doporučené konfiguraci pro ASP.NET Core je aplikace hostovaná pomocí modulu ASP.NET Core (ANCM) pro službu IIS, Nginx nebo Apache. Proxy servery, nástroje pro vyrovnávání zatížení a další síťová zařízení často zakrývají informace o požadavku před dosažením aplikace:

  • Když se požadavky HTTPS přesměrují přes PROTOKOL HTTP, původní schéma (HTTPS) se ztratí a musí se předávat v hlavičce.
  • Vzhledem k tomu, že aplikace přijímá požadavek z proxy serveru, a ne jeho skutečný zdroj v internetu nebo podnikové síti, musí se v hlavičce předávat také původní IP adresa klienta.

Tyto informace můžou být důležité při zpracování požadavků, například při přesměrování, ověřování, generování propojení, vyhodnocení zásad a geografické poloze klienta.

Aplikace určené ke spuštění ve webové farmě by si měly přečíst jak hostovat ASP.NET Core ve webové farmě.

Přeposílané hlavičky

Podle konvence předávají proxy informace v hlavičkách HTTP.

Hlavička Popis
X-Forwarded-For (XFF) Obsahuje informace o klientovi, který inicioval požadavek a následné proxy servery v řetězci proxy serverů. Tento parametr může obsahovat IP adresy a volitelně čísla portů. V řetězci proxy serverů první parametr indikuje klienta, u kterého byl požadavek proveden jako první. Následující identifikátory proxy serveru následují. Poslední proxy server v řetězci není v seznamu parametrů. IP adresa posledního proxy serveru a volitelně číslo portu jsou k dispozici jako vzdálená IP adresa v přenosové vrstvě.
X-Forwarded-Proto (XFP) Hodnota původního schématu, HTTP nebo HTTPS. Hodnota může být také seznam schémat, pokud požadavek prochází více proxy serverů.
X-Forwarded-Host (XFH) Původní hodnota pole hlavička Host. Proxy servery obvykle neupravují hlavičku hostitele. Informace o ohrožení zabezpečení, které má vliv na systémy, ve kterých proxy server neověřuje nebo neomezuje hlavičky hostitele na známé dobré hodnoty, najdete v článku CVE-2018-0787 , který obsahuje informace o ohrožení zabezpečení spočívající ve zvýšení oprávnění.
X-Forwarded-Prefix Původní základní cesta požadovaná klientem. Tato hlavička může být užitečná pro aplikace, které správně generují adresy URL, přesměrování nebo odkazy zpět na klienta.

Middleware pro předávané hlavičky, ForwardedHeadersMiddleware, přečte tyto hlavičky a vyplní odpovídající pole v HttpContext.

Aktualizace middlewaru:

Další informace o předchozím problému najdete v tomto problému na GitHubu.

Výchozí nastavení middlewaru pro předávané hlavičky lze nakonfigurovat. Výchozí nastavení:

  • Mezi aplikací a zdrojem požadavků je jenom jeden proxy server .
  • Pro známé proxy a známé sítě jsou nakonfigurované pouze adresy zpětné smyčky.
  • Přeposílané hlavičky mají název X-Forwarded-For, X-Forwarded-ProtoX-Forwarded-Host a X-Forwarded-Prefix.
  • Hodnota ForwardedHeaders je ForwardedHeaders.None. Požadované služby předávání musí být nastavené tady, aby bylo možné middleware povolit.

Ne všechna síťová zařízení přidávají hlavičky X-Forwarded-For a X-Forwarded-Proto bez dodatečné konfigurace. Pokud proxy žádosti neobsahují tyto hlavičky, obraťte se na pokyny výrobce vašeho zařízení, když dorazí k aplikaci. Pokud zařízení používá jiné názvy hlaviček než X-Forwarded-For a X-Forwarded-Proto, nastavte možnosti ForwardedForHeaderName a ForwardedProtoHeaderName tak, aby odpovídaly názvům hlaviček používaným zařízením. Další informace najdete v tématu Možnosti middlewaru předávaných hlaviček a Konfigurace proxy serveru, který používá různé názvy hlaviček.

Modul IIS/IIS Express a modul ASP.NET Core

Integrační middleware služby IIS ve výchozím nastavení povoluje middleware pro předávané hlavičky, když je aplikace hostovaná mimo proces za službou IIS a modulem ASP.NET Core Module (ANCM) pro IIS. Middleware pro předávané hlavičky je aktivován tak, aby se v kanálu zpracování middlewaru spouštěl jako první, s omezenou konfigurací specifickou pro modul ASP.NET Core. Omezená konfigurace je způsobena obavami z nedůvěry k předávaným hlavičkám, například IP spoofing. Middleware je nakonfigurovaný tak, aby předával hlavičky X-Forwarded-For a X-Forwarded-Proto a je omezen na jeden proxy server běžící na místním hostiteli. Pokud je potřeba další konfigurace, viz možnosti middlewaru pro předávané hlavičky.

Další scénáře proxy serveru a nástroje pro vyrovnávání zatížení

S výjimkou použití Integrace s IIS při hostování mimo proces není middleware pro předávané hlavičky ve výchozím nastavení povolen. Middleware předávaných hlaviček musí být povolený, aby aplikace zpracovávala hlavičky přeposílané pomocí UseForwardedHeaders. Po povolení middlewaru, pokud nejsou specifikovány žádné ForwardedHeadersOptions k middlewaru, výchozí ForwardedHeadersOptions.ForwardedHeaders jsou ForwardedHeaders.None.

Nakonfigurujte middleware pomocí ForwardedHeadersOptions tak, aby předával hlavičky X-Forwarded-For a X-Forwarded-Proto.

Pořadí middlewaru pro předávané hlavičky

Middleware pro předávané hlavičky by se měl spouštět před ostatním middlewarem. Toto řazení zajišťuje, že middleware, který spoléhá na informace předávaných hlaviček, může využívat hodnoty hlaviček ke zpracování. Middleware pro přeposílané hlavičky lze spustit po diagnostice a zpracování chyb, ale musí být spuštěn před voláním UseHsts:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseForwardedHeaders();
    app.UseHsts();
}
else
{
    app.UseDeveloperExceptionPage();
    app.UseForwardedHeaders();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Případně volejte UseForwardedHeaders před diagnostikou:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Poznámka:

Nejsou-li žádné ForwardedHeadersOptions zadány nebo použity přímo na rozšiřující metodě s UseForwardedHeaders, výchozí hlavičky pro předávání jsou ForwardedHeaders.None. Vlastnost ForwardedHeaders musí být nakonfigurována s hlavičkami pro předávání.

Konfigurace Nginx

Pokud chcete předávat hlavičky X-Forwarded-For a X-Forwarded-Proto, přečtěte si téma Host ASP.NET Core v Linuxu s Nginxem.

Konfigurace Apache

X-Forwarded-For se přidá automaticky. Další informace najdete v tématu Apache modul mod_proxy: Záhlaví požadavků reverzního proxy serveru.

Možnosti middlewaru pro předávané hlavičky

ForwardedHeadersOptions řídí chování middlewaru pro předávané hlavičky. Následující příklad změní výchozí hodnoty:

  • Omezuje počet položek v přeposlaných záhlavích na 2.
  • Přidá známou adresu proxy serveru .127.0.10.1
  • Změní název přeposlané hlavičky z výchozí X-Forwarded-For hodnoty na X-Forwarded-For-My-Custom-Header-Name.
using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.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";
});

var app = builder.Build();

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();
Možnost Popis
AllowedHosts Omezuje hostitele na hodnoty zadané v hlavičce X-Forwarded-Host.
  • Hodnoty se porovnávají s použitím pořadí bez rozlišování velkých a malých písmen.
  • Čísla portů musí být vyloučena.
  • Pokud je seznam prázdný, jsou všichni hostitelé povoleni.
  • Zástupný znak * nejvyšší úrovně umožňuje všem neprázdným hostitelům.
  • Zástupné znaky subdomény jsou povolené, ale nepočítají s kořenovou doménou. Například odpovídá subdoméně*.contoso.com, foo.contoso.com ale ne kořenové doméně contoso.com.
  • Názvy hostitelů Unicode jsou povoleny, ale jsou převedeny na punycode pro porovnávání.
  • Adresy IPv6 musí obsahovat ohraničující hranaté závorky a musí být v konvenční podobě (například [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). Adresy IPv6 nejsou speciální, aby bylo možné zkontrolovat logickou rovnost mezi různými formáty a neprovádí se kanonizace.
  • Nepoužití omezení povolených hostitelů může umožnit kyberútočníkovi falšování odkazů generovaných službou.
Výchozí hodnota je prázdná IList<string>.
ForwardedForHeaderName Místo hlavičky určené ForwardedHeadersDefaults.XForwardedForHeaderName použijte hlavičku určenou touto vlastností. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-For , ale k předávání informací používá jiné hlavičky.

Výchozí hodnota je X-Forwarded-For.
ForwardedHeaders Určuje, kteří přesměrovávače by se měly zpracovat. Podívejte se na ForwardedHeaders Enum pro seznam polí, která se vztahují. Typické hodnoty přiřazené této vlastnosti jsou ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

Výchozí hodnota je ForwardedHeaders.None.
ForwardedHostHeaderName Místo hlavičky určené ForwardedHeadersDefaults.XForwardedHostHeaderName použijte hlavičku určenou touto vlastností. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Host , ale k předávání informací používá jiné hlavičky.

Výchozí hodnota je X-Forwarded-Host.
ForwardedProtoHeaderName Místo hlavičky určené touto vlastností použijte hlavičku určenou ForwardedHeadersDefaults.XForwardedProtoHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Proto , ale k předávání informací používá jiné hlavičky.

Výchozí hodnota je X-Forwarded-Proto.
ForwardLimit Omezuje počet položek v záhlavích, která se zpracovávají. Nastavte null k deaktivaci limitu. Mělo by se to provést pouze v případě, že jsou nakonfigurovány buď KnownProxies, nebo KnownNetworks. Nastavení jinénull hodnoty je preventivní krok (ale ne záruka), který chrání před chybně nakonfigurovanými proxy servery a škodlivými požadavky přicházejícími z postranních kanálů v síti.

Middleware pro předávané hlavičky zpracovává hlavičky v opačném pořadí, zprava doleva. Pokud se použije výchozí hodnota (1), zpracuje se pouze nejpravější hodnota z hlaviček, pokud se nezvětší hodnota ForwardLimit.

Výchozí hodnota je 1.
KnownNetworks Rozsahy adres známých sítí k akceptování předávaných hlaviček. Zadejte rozsahy IP adres pomocí zápisu CIDR (Classless Interdomain Routing).

Pokud server používá sokety se dvěma režimy, adresy IPv4 se zadají ve formátu IPv6 (například 10.0.0.1 v IPv4 reprezentované jako IPv6).::ffff:10.0.0.1 Viz IPAddress.MapToIPv6. Zjistěte, jestli je tento formát vyžadován pomocí httpContext.Connection.RemoteIpAddress.

Výchozí hodnota je IList<IPNetwork>obsahující jednu položku pro .new IPNetwork(IPAddress.Loopback, 8)
KnownProxies Adresy známých proxy serverů pro příjem předávaných hlaviček. Slouží KnownProxies k určení přesné shody IP adres.

Pokud server používá sokety se dvěma režimy, adresy IPv4 se zadají ve formátu IPv6 (například 10.0.0.1 v IPv4 reprezentované jako IPv6).::ffff:10.0.0.1 Viz IPAddress.MapToIPv6. Zjistěte, jestli je tento formát vyžadován pomocí httpContext.Connection.RemoteIpAddress.

Výchozí hodnota je IList<IPAddress>obsahující jednu položku pro .IPAddress.IPv6Loopback
OriginalForHeaderName Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XOriginalForHeaderName.

Výchozí hodnota je X-Original-For.
OriginalHostHeaderName Použijte hlavičku určenou touto vlastností místo hlavičky určené ForwardedHeadersDefaults.XOriginalHostHeaderName.

Výchozí hodnota je X-Original-Host.
OriginalProtoHeaderName Použijte hlavičku určenou touto vlastností místo toho, kterou určuje ForwardedHeadersDefaults.XOriginalProtoHeaderName.

Výchozí hodnota je X-Original-Proto.
RequireHeaderSymmetry Vyžaduje, aby počet hodnot záhlaví byl synchronizován mezi zpracovávanými ForwardedHeadersOptions.ForwardedHeaders.

Výchozí hodnota v ASP.NET Core 1.x je true. Výchozí hodnota v ASP.NET Core 2.0 nebo novější je false.

Scénáře a případy použití

Pokud není možné přidávat přeposílané hlavičky a všechny požadavky jsou zabezpečené

V některých případech nemusí být možné přidat předávané hlavičky do požadavků přesměrovaných do aplikace. Pokud proxy server vynucuje, že všechny veřejné externí požadavky jsou HTTPS, můžete schéma nastavit ručně před použitím libovolného typu middlewaru:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

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

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Tento kód lze zakázat pomocí proměnné prostředí nebo jiného nastavení konfigurace ve vývojovém nebo přípravném prostředí:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

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

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Práce se základní cestou a proxy servery, které mění cestu požadavku

Některé proxy servery předávají cestu beze změny, ale s kořenovou cestou aplikace, která by se měla odebrat, aby směrování fungovalo správně. Middleware UsePathBaseExtensions.UsePathBase rozdělí cestu na HttpRequest.Path a základní cestu aplikace na HttpRequest.PathBase.

Pokud je /foo základní cestou aplikace pro proxy cestu předanou jako /foo/api/1, middleware nastaví Request.PathBase na /foo a Request.Path na /api/1 pomocí následujícího příkazu:

app.UsePathBase("/foo");
// ...
app.UseRouting();

Poznámka:

Při použití WebApplication (viz Migrace z ASP.NET Core v .NET 5 na .NET 6) musí být app.UseRouting volána po UsePathBase, aby směrovací middleware mohl sledovat upravenou cestu před porovnáním tras. Jinak dochází ke spárování tras předtím, než UsePathBase přepíše cestu, jak je popsáno v middleware ASP.NET Core a Směrování v ASP.NET Core.

Původní cesta a základ cesty se znovu použijí při opětovném zavolání middleware v opačném pořadí. Další informace o zpracování objednávek middlewaru najdete v tématu ASP.NET Core middleware.

Pokud proxy server ořízne cestu (například přesměrování na ), přesměrování a odkazy jsou opraveny nastavením vlastnosti požadavku PathBase.

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

Pokud proxy přidává data cesty, odstraňte část této cesty, aby se opravily přesměrování a odkazy pomocí StartsWithSegments a nastavením vlastnosti Path.

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

    return next(context);
});

Konfigurace proxy serveru, který používá různé názvy hlaviček

Pokud proxy server nepoužívá hlavičky pojmenované X-Forwarded-For a X-Forwarded-Proto předávat adresu proxy serveru nebo port a informace o schématu původu, nastavte ForwardedForHeaderName a ForwardedProtoHeaderName možnosti tak, aby odpovídaly názvům hlaviček používaných proxy serverem:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedForHeaderName = "HeaderNamUsedByProxy_X-Forwarded-For_Header";
    options.ForwardedProtoHeaderName = "HeaderNamUsedByProxy_X-Forwarded-Proto_Header";
});

var app = builder.Build();

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Přeposlat schéma pro reverzní proxy servery Linux a ne-IIS.

Aplikace, které volají UseHttpsRedirection a UseHsts umístí web do nekonečné smyčky, pokud jsou nasazené do služby Azure Linux App Service, virtuálního počítače Azure s Linuxem nebo za jakýmkoli jiným reverzním proxy serverem kromě služby IIS. Reverzní proxy server ukončí protokol TLS a Kestrel není informován o správném schématu požadavků. OAuth a OIDC také v této konfiguraci selžou, protože generují nesprávné přesměrování. UseIISIntegration přidává a konfiguruje middleware pro předávané hlavičky při běhu za IIS, ale pro Linux (integrace s Apache nebo Nginx) neexistuje žádné odpovídající automatické nastavení.

Chcete-li v scénářích mimo IIS předávat protokol z proxy serveru, povolte middleware pro předávané hlavičky nastavením ASPNETCORE_FORWARDEDHEADERS_ENABLED na true. Upozornění: Tento příznak používá nastavení navržená pro cloudová prostředí a neaktivuje funkce, jako je omezení, ze kterých IP adres jsou přijímáni přeposílatelé.

Předávání certifikátů

Azurový

Pokud chcete nakonfigurovat službu Aplikace Azure service pro předávání certifikátů, přečtěte si téma Konfigurace vzájemného ověřování TLS pro službu Aplikace Azure Service. Následující pokyny se týkají konfigurace aplikace ASP.NET Core.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
    options.CertificateHeader = "X-ARR-ClientCert");

var app = builder.Build();

app.UseCertificateForwarding();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();
app.UseAuthentication();

app.MapRazorPages();

app.Run();

Další webové proxy servery

Pokud se používá proxy server, který není IIS nebo směrování žádostí o aplikaci Azure App Service (ARR), nakonfigurujte proxy server tak, aby předával certifikát, který přijal v hlavičce HTTP.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
    options.CertificateHeader = "YOUR_CERTIFICATE_HEADER_NAME");

var app = builder.Build();

app.UseCertificateForwarding();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();
app.UseAuthentication();

app.MapRazorPages();

app.Run();

Pokud proxy server nekóduje certifikát v base64, jako je tomu u Nginx, nastavte možnost HeaderConverter. Představte si následující příklad:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
{
    options.CertificateHeader = "YOUR_CUSTOM_HEADER_NAME";
    options.HeaderConverter = (headerValue) =>
    {
        // Conversion logic to create an X509Certificate2.
        var clientCertificate = ConversionLogic.CreateAnX509Certificate2();
        return clientCertificate;
    };
});

var app = builder.Build();

app.UseCertificateForwarding();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();
app.UseAuthentication();

app.MapRazorPages();

app.Run();

Odstraňování potíží

Pokud hlavičky nejsou přeposílané podle očekávání, povolte protokolování na debuga protokolování požadavků HTTP. UseHttpLogging musí být voláno po UseForwardedHeaders:

using Microsoft.AspNetCore.HttpLogging;
using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddHttpLogging(options =>
{
    options.LoggingFields = HttpLoggingFields.RequestPropertiesAndHeaders;
});

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

var app = builder.Build();

app.UseForwardedHeaders();
app.UseHttpLogging();

app.Use(async (context, next) =>
{
    // Connection: RemoteIp
    app.Logger.LogInformation("Request RemoteIp: {RemoteIpAddress}",
        context.Connection.RemoteIpAddress);

    await next(context);
});

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Pokud v dané hlavičce existuje více hodnot, předané hlavičky middlewaru zpracovávají hlavičky v opačném pořadí zprava doleva. Výchozí hodnota ForwardLimit je 1 (jedna), takže pouze hodnota nejvíce vpravo ze záhlaví se zpracuje, pokud se nezvětší ForwardLimit hodnota.

Původní vzdálená IP adresa požadavku musí odpovídat položce v seznamech KnownProxies nebo KnownNetworks před tím, než jsou zpracovány předávané hlavičky. Toto omezuje falšování hlaviček, tím že nepřijímá předávání z nedůvěryhodných proxy serverů. Když se zjistí neznámý proxy server, protokolování označuje adresu proxy serveru:

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

V předchozím příkladu je 10.0.0.100 proxy server. Pokud je server důvěryhodným proxy serverem, přidejte IP adresu serveru do KnownProxiesnebo přidejte důvěryhodnou síť do KnownNetworks. Další informace najdete v oddílu možnosti middlewaru pro přeposílané hlavičky.

using Microsoft.AspNetCore.HttpOverrides;
using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseForwardedHeaders();
    app.UseHsts();
}
else
{
    app.UseDeveloperExceptionPage();
    app.UseForwardedHeaders();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Pokud chcete zobrazit protokoly, přidejte "Microsoft.AspNetCore.HttpLogging": "Information" do appsettings.Development.json souboru:

{
  "DetailedErrors": true,
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.HttpLogging": "Information"
    }
  }
}

Důležité

Povolit předávání hlaviček jenom důvěryhodným proxy serverům a sítím. V opačném případě jsou možné útoky falšování identity IP adres.

Další materiály

V doporučené konfiguraci pro ASP.NET Core je aplikace hostovaná pomocí modulu IIS/ASP.NET Core, Nginx nebo Apache. Proxy servery, nástroje pro vyrovnávání zatížení a další síťová zařízení často zakrývají informace o požadavku před dosažením aplikace:

  • Když se požadavky HTTPS přesměrují přes PROTOKOL HTTP, původní schéma (HTTPS) se ztratí a musí se předávat v hlavičce.
  • Vzhledem k tomu, že aplikace přijímá požadavek z proxy serveru, a ne jeho skutečný zdroj v internetu nebo podnikové síti, musí se v hlavičce předávat také původní IP adresa klienta.

Tyto informace můžou být důležité při zpracování požadavků, například při přesměrování, ověřování, generování propojení, vyhodnocení zásad a geografické poloze klienta.

Přeposílané hlavičky

Podle konvence předávají proxy informace v hlavičkách HTTP.

Hlavička Popis
X-Forwarded-For Obsahuje informace o klientovi, který inicioval požadavek a následné proxy servery v řetězci proxy serverů. Tento parametr může obsahovat IP adresy (a volitelně čísla portů). V řetězci proxy serverů první parametr indikuje klienta, u kterého byl požadavek proveden jako první. Následující identifikátory proxy serveru následují. Poslední proxy server v řetězci není v seznamu parametrů. IP adresa posledního proxy serveru a volitelně číslo portu jsou k dispozici jako vzdálená IP adresa v přenosové vrstvě.
X-Forwarded-Proto Hodnota původního schématu (HTTP/HTTPS). Hodnota může být také seznam schémat, pokud požadavek prochází více proxy serverů.
X-Forwarded-Host Původní hodnota pole hlavička Host. Proxy servery obvykle neupravují hlavičku hostitele. Informace o ohrožení zabezpečení, které má vliv na systémy, ve kterých proxy server neověřuje nebo neomezuje hlavičky hostitele na známé dobré hodnoty, najdete v článku CVE-2018-0787 , který obsahuje informace o ohrožení zabezpečení spočívající ve zvýšení oprávnění.

Middleware pro předávané hlavičky (ForwardedHeadersMiddleware) tyto hlavičky načte a vyplní odpovídající pole v objektu HttpContext.

Aktualizace middlewaru:

Další informace o předchozím problému najdete v tomto problému na GitHubu.

Výchozí nastavení middlewaru předávaných hlaviček je možné nakonfigurovat. Výchozí nastavení:

  • Mezi aplikací a zdrojem požadavků je jenom jeden proxy server .
  • Pro známé proxy a známé sítě jsou nakonfigurované pouze adresy zpětné smyčky.
  • Přeposílané hlavičky jsou pojmenované X-Forwarded-For a X-Forwarded-Proto.
  • Hodnota ForwardedHeaders je ForwardedHeaders.None a požadované předávací prvky musí být nastaveny zde, aby bylo možné aktivovat middleware.

Ne všechna síťová zařízení přidávají hlavičky X-Forwarded-For a X-Forwarded-Proto bez dodatečné konfigurace. Pokud proxy žádosti neobsahují tyto hlavičky, obraťte se na pokyny výrobce vašeho zařízení, když dorazí k aplikaci. Pokud zařízení používá jiné názvy hlaviček než X-Forwarded-For a X-Forwarded-Proto, nastavte možnosti ForwardedForHeaderName a ForwardedProtoHeaderName tak, aby odpovídaly názvům hlaviček používaným zařízením. Další informace najdete v tématu Možnosti middlewaru předávaných hlaviček a Konfigurace proxy serveru, který používá různé názvy hlaviček.

Modul IIS/IIS Express a modul ASP.NET Core

Integrační middleware IIS ve výchozím nastavení povoluje middleware pro předávané hlavičky, když je aplikace hostovaná v režimu out-of-process za serverem IIS a modulem ASP.NET Core. Middleware pro předávané hlavičky je nakonfigurován tak, aby se v kanálu middleware spouštěl jako první, a to s omezenou konfigurací specifickou pro modul ASP.NET Core kvůli obavám o důvěryhodnost předávaných hlaviček (například podvržení IP adresy). Middleware je nakonfigurovaný tak, aby předával hlavičky X-Forwarded-For a X-Forwarded-Proto a je omezen na jeden proxy server běžící na místním hostiteli. Pokud je vyžadována další konfigurace, viz možnosti middlewaru pro předávání hlaviček.

Další scénáře proxy serveru a nástroje pro vyrovnávání zatížení

Kromě použití Integrace IIS při hostování mimo proces není middleware pro předávané hlavičky ve výchozím nastavení povolen. Middleware předávaných hlaviček musí být povolený, aby aplikace zpracovávala hlavičky přeposílané pomocí UseForwardedHeaders. Po povolení middlewaru, pokud nejsou specifikovány žádné ForwardedHeadersOptions k middlewaru, výchozí ForwardedHeadersOptions.ForwardedHeaders jsou ForwardedHeaders.None.

Nakonfigurujte middleware tak ForwardedHeadersOptions, aby předával hlavičky X-Forwarded-For a X-Forwarded-Proto v Startup.ConfigureServices souboru.

Pořadí middlewaru pro předávané hlavičky

Middleware pro předávané hlavičky by měl běžet před ostatním middlewarem. Toto řazení zajišťuje, že middleware, který spoléhá na informace předávaných hlaviček, může využívat hodnoty hlaviček ke zpracování. Middleware předávaných hlaviček může běžet po diagnostice a zpracování chyb, ale musí se spustit před voláním UseHsts:

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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders =
                ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseForwardedHeaders();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseForwardedHeaders();
            app.UseHsts();
        }

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

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

Případně volejte UseForwardedHeaders před diagnostikou:

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

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

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

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Poznámka:

Pokud nejsou ForwardedHeadersOptions zadány v Startup.ConfigureServices nebo přímo do rozšiřující metody s UseForwardedHeaders, výchozí hlavičky pro přesměrování jsou ForwardedHeaders.None. Vlastnost ForwardedHeaders musí být nakonfigurována s hlavičkami pro předávání.

Konfigurace Nginx

Pokud chcete předávat hlavičky X-Forwarded-For a X-Forwarded-Proto, přečtěte si téma Host ASP.NET Core v Linuxu s Nginxem.

Konfigurace Apache

X-Forwarded-For se přidá automaticky (viz modul Apache mod_proxy: Hlavičky reverzních požadavků proxy serveru).

Možnosti middlewaru předávaných hlaviček

ForwardedHeadersOptions určují chování middlewaru pro předávané hlavičky. Následující příklad změní výchozí hodnoty:

  • Omezte počet položek v přeposlaných záhlavích na 2.
  • Přidejte známou 127.0.10.1adresu proxy serveru .
  • Změňte název přeposlané hlavičky z výchozí X-Forwarded-For hodnoty na 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";
});
Možnost Popis
AllowedHosts Omezuje hostitele na hodnoty zadané v hlavičce X-Forwarded-Host.
  • Hodnoty se porovnávají s použitím pořadí bez rozlišování velkých a malých písmen.
  • Čísla portů musí být vyloučena.
  • Pokud je seznam prázdný, jsou všichni hostitelé povoleni.
  • Zástupný znak * nejvyšší úrovně umožňuje všem neprázdným hostitelům.
  • Zástupné znaky subdomény jsou povolené, ale nepočítají s kořenovou doménou. Například odpovídá subdoméně*.contoso.com, foo.contoso.com ale ne kořenové doméně contoso.com.
  • Názvy hostitelů Unicode jsou povoleny, ale jsou převedeny na punycode pro porovnávání.
  • Adresy IPv6 musí obsahovat ohraničující hranaté závorky a musí být v konvenční podobě (například [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). Adresy IPv6 nejsou speciální, aby bylo možné zkontrolovat logickou rovnost mezi různými formáty a neprovádí se kanonizace.
  • Nepoužití omezení povolených hostitelů může umožnit kyberútočníkovi falšování odkazů generovaných službou.
Výchozí hodnota je prázdná IList<string>.
ForwardedHeaders Určuje, kteří přesměrovávače by se měly zpracovat. Podívejte se na ForwardedHeaders Enum pro seznam polí, která se vztahují. Typické hodnoty přiřazené této vlastnosti jsou ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

Výchozí hodnota je ForwardedHeaders.None.
ForwardedForHeaderName Místo hlavičky určené ForwardedHeadersDefaults.XForwardedForHeaderName použijte hlavičku určenou touto vlastností. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-For , ale k předávání informací používá jiné hlavičky.

Výchozí hodnota je X-Forwarded-For.
ForwardedHostHeaderName Místo hlavičky určené ForwardedHeadersDefaults.XForwardedHostHeaderName použijte hlavičku určenou touto vlastností. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Host , ale k předávání informací používá jiné hlavičky.

Výchozí hodnota je X-Forwarded-Host.
ForwardedProtoHeaderName Místo hlavičky určené touto vlastností použijte hlavičku určenou ForwardedHeadersDefaults.XForwardedProtoHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Proto , ale k předávání informací používá jiné hlavičky.

Výchozí hodnota je X-Forwarded-Proto.
ForwardedPrefixHeaderName Použijte hlavičku určenou touto vlastností místo hlavičky určené ForwardedHeadersDefaults.XForwardedPrefixHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Prefix , ale k předávání informací používá jiné hlavičky.

Výchozí hodnota je X-Forwarded-Prefix.
ForwardLimit Omezuje počet položek v záhlavích, která se zpracovávají. Nastavte null k deaktivaci limitu. Mělo by se to provést pouze v případě, že jsou nakonfigurovány buď KnownProxies, nebo KnownNetworks. Nastavení jinénull hodnoty je preventivní krok (ale ne záruka), který chrání před chybně nakonfigurovanými proxy servery a škodlivými požadavky přicházejícími z postranních kanálů v síti.

Middleware pro předávané hlavičky zpracovává hlavičky v opačném pořadí, zprava doleva. Pokud se použije výchozí hodnota (1), zpracuje se pouze nejpravější hodnota z hlaviček, pokud se nezvětší hodnota ForwardLimit.

Výchozí hodnota je 1.
KnownNetworks Rozsahy adres známých sítí k akceptování předávaných hlaviček. Zadejte rozsahy IP adres pomocí zápisu CIDR (Classless Interdomain Routing).

Pokud server používá sokety se dvěma režimy, adresy IPv4 se zadají ve formátu IPv6 (například 10.0.0.1 v IPv4 reprezentované jako IPv6).::ffff:10.0.0.1 Viz IPAddress.MapToIPv6. Zjistěte, jestli je tento formát vyžadován pomocí httpContext.Connection.RemoteIpAddress.

Výchozí hodnota je IList<IPNetwork>obsahující jednu položku pro .new IPNetwork(IPAddress.Loopback, 8)
KnownProxies Adresy známých proxy serverů pro příjem předávaných hlaviček. Slouží KnownProxies k určení přesné shody IP adres.

Pokud server používá sokety se dvěma režimy, adresy IPv4 se zadají ve formátu IPv6 (například 10.0.0.1 v IPv4 reprezentované jako IPv6).::ffff:10.0.0.1 Viz IPAddress.MapToIPv6. Zjistěte, jestli je tento formát vyžadován pomocí httpContext.Connection.RemoteIpAddress.

Výchozí hodnota je IList<IPAddress>obsahující jednu položku pro .IPAddress.IPv6Loopback
OriginalForHeaderName Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XOriginalForHeaderName.

Výchozí hodnota je X-Original-For.
OriginalHostHeaderName Použijte hlavičku určenou touto vlastností místo hlavičky určené ForwardedHeadersDefaults.XOriginalHostHeaderName.

Výchozí hodnota je X-Original-Host.
OriginalProtoHeaderName Použijte hlavičku určenou touto vlastností místo toho, kterou určuje ForwardedHeadersDefaults.XOriginalProtoHeaderName.

Výchozí hodnota je X-Original-Proto.
OriginalPrefixHeaderName Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XOriginalPrefixHeaderName.

Výchozí hodnota je X-Original-Prefix.
RequireHeaderSymmetry Vyžaduje, aby počet hodnot záhlaví byl synchronizován mezi zpracovávanými ForwardedHeadersOptions.ForwardedHeaders.

Výchozí hodnota v ASP.NET Core 1.x je true. Výchozí hodnota v ASP.NET Core 2.0 nebo novější je false.

Scénáře a případy použití

Pokud není možné přidávat přeposílané hlavičky a všechny požadavky jsou zabezpečené

V některých případech nemusí být možné přidat předávané hlavičky do požadavků přesměrovaných do aplikace. Pokud proxy server vynucuje, že všechny veřejné externí požadavky jsou HTTPS, můžete schéma před použitím libovolného typu middlewaru nastavit Startup.Configure ručně:

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

Tento kód může být zakázán s proměnnou prostředí nebo jiným nastavením konfigurace ve vývojovém nebo přípravném prostředí.

Řešení základní cesty a proxy serverů, které mění cestu požadavku

Některé proxy servery předávají cestu beze změny, ale s kořenovou cestou aplikace, která by se měla odebrat, aby směrování fungovalo správně. Middleware UsePathBaseExtensions.UsePathBase rozdělí cestu na HttpRequest.Path a základní cestu aplikace na HttpRequest.PathBase.

Pokud je /foo základní cestou aplikace pro proxy cestu předanou jako /foo/api/1, middleware nastaví Request.PathBase na /foo a Request.Path na /api/1 pomocí následujícího příkazu:

app.UsePathBase("/foo");

Původní cesta a základ cesty se znovu použijí při opětovném zavolání middleware v opačném pořadí. Další informace o zpracování objednávek middlewaru najdete v tématu ASP.NET Core middleware.

Pokud proxy server ořízne cestu (například přesměrování na ), přesměrování a odkazy jsou opraveny nastavením vlastnosti požadavku PathBase.

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

Pokud proxy přidává data cesty, odstraňte část této cesty, aby se opravily přesměrování a odkazy pomocí StartsWithSegments a nastavením vlastnosti Path.

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

    return next();
});

Konfigurace proxy serveru, který používá různé názvy hlaviček

Pokud proxy server nepoužívá hlavičky pojmenované X-Forwarded-For a X-Forwarded-Proto předávat adresu proxy serveru nebo port a informace o schématu původu, nastavte ForwardedForHeaderName a ForwardedProtoHeaderName možnosti tak, aby odpovídaly názvům hlaviček používaných proxy serverem:

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

Přeposlat schéma pro reverzní proxy servery Linux a ne-IIS.

Aplikace, které volají UseHttpsRedirection a UseHsts umístí web do nekonečné smyčky, pokud jsou nasazené do služby Azure Linux App Service, virtuálního počítače Azure s Linuxem nebo za jakýmkoli jiným reverzním proxy serverem kromě služby IIS. Reverzní proxy server ukončí protokol TLS a Kestrel není informován o správném schématu požadavků. OAuth a OIDC také v této konfiguraci selžou, protože generují nesprávné přesměrování. UseIISIntegration přidává a konfiguruje middleware pro předávané hlavičky při spuštění za IIS, ale pro Linux (integrace s Apache nebo Nginx) neexistuje odpovídající automatická konfigurace.

Pokud chcete schéma předat z proxy serveru ve scénářích, které nejsou službami IIS, přidejte a nakonfigurujte middleware předávaných hlaviček. V Startup.ConfigureServicesaplikaci použijte následující kód:

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

Předávání certifikátů

Azurový

Pokud chcete nakonfigurovat službu Aplikace Azure service pro předávání certifikátů, přečtěte si téma Konfigurace vzájemného ověřování TLS pro službu Aplikace Azure Service. Následující pokyny se týkají konfigurace aplikace ASP.NET Core.

Před Startup.Configurevoláním app.UseAuthentication();přidejte následující kód:

app.UseCertificateForwarding();

Nakonfigurujte middleware pro předávání certifikátů tak, aby zadal název hlavičky, který Azure používá. Do Startup.ConfigureServicespole přidejte následující kód pro konfiguraci hlavičky, ze které middleware vytvoří certifikát:

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

Další webové proxy servery

Pokud se používá proxy server, který není IIS nebo směrování žádostí o aplikaci Azure App Service (ARR), nakonfigurujte proxy server tak, aby předával certifikát, který přijal v hlavičce HTTP. Před Startup.Configurevoláním app.UseAuthentication();přidejte následující kód:

app.UseCertificateForwarding();

Nakonfigurujte middleware pro předávání certifikátů tak, aby zadal název hlavičky. Do Startup.ConfigureServicespole přidejte následující kód pro konfiguraci hlavičky, ze které middleware vytvoří certifikát:

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

Pokud proxy server base64 nekóduje certifikát, stejně jako v případě Nginx, nastavte možnost HeaderConverter. Podívejte se na následující příklad v 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;
    }
});

Odstraňování potíží

Pokud se hlavičky nepřesměrují podle očekávání, povolte protokolování. Pokud protokoly neobsahují dostatečné informace pro řešení problému, uveďte výčet hlaviček požadavků přijatých serverem. K zapisování hlaviček požadavků do odpovědi aplikace nebo k protokolování těchto hlaviček použijte in-line middleware.

Pokud chcete napsat hlavičky do odpovědi aplikace, umístěte následující koncový middleware hned za volání UseForwardedHeaders v 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}");
});

Místo textu odpovědi můžete zapisovat do protokolů. Umožněním zápisu do protokolů může web i při ladění fungovat normálně.

Zápis protokolů místo textu odpovědi:

app.Use(async (context, next) =>
{
    // Request method, scheme, path, and base 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);
    _logger.LogDebug("Request Path Base: {PathBase}", context.Request.PathBase);

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

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

    await next();
});

Při zpracování X-Forwarded-{For|Proto|Host|Prefix} se hodnoty přesunou do X-Original-{For|Proto|Host|Prefix}. Pokud v dané hlavičce existuje více hodnot, předané hlavičky middlewaru zpracovávají hlavičky v opačném pořadí zprava doleva. Výchozí hodnota ForwardLimit je 1 (jedna), takže pouze hodnota nejvíce vpravo ze záhlaví se zpracuje, pokud se nezvětší ForwardLimit hodnota.

Původní vzdálená IP adresa požadavku musí odpovídat položce v seznamech KnownProxies nebo KnownNetworks před tím, než jsou zpracovány předávané hlavičky. Toto omezuje falšování hlaviček, tím že nepřijímá předávání z nedůvěryhodných proxy serverů. Když se zjistí neznámý proxy server, protokolování označuje adresu proxy serveru:

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

V předchozím příkladu je 10.0.0.100 proxy server. Pokud je server důvěryhodným proxy serverem, přidejte IP adresu serveru do KnownProxies (nebo přidejte důvěryhodnou síť) do KnownNetworksStartup.ConfigureServices. Další informace najdete v oddílu možnosti middlewaru pro předávané hlavičky.

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

Důležité

Povolit předávání hlaviček jenom důvěryhodným proxy serverům a sítím. V opačném případě jsou možné útoky falšování identity IP adres.

Další materiály