Delen via


ASP.NET Core configureren voor gebruik met proxyservers en load balancers

Notitie

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikelvoor de huidige release.

Door Chris Ross

In de aanbevolen configuratie voor ASP.NET Core wordt de app gehost met behulp van ASP.NET Core Module (ANCM) voor IIS-, Nginx of Apache. Proxyservers, load balancers en andere netwerkapparaten verhullen vaak informatie over de aanvraag voordat deze de app bereikt:

  • Wanneer HTTPS-aanvragen via HTTP worden geproxied, gaat het oorspronkelijke schema (HTTPS) verloren en moet het worden doorgestuurd in een header.
  • Omdat een app een aanvraag van de proxy ontvangt en niet de werkelijke bron op internet of het bedrijfsnetwerk, moet het ip-adres van de oorspronkelijke client ook worden doorgestuurd in een header.

Deze informatie kan belangrijk zijn bij het verwerken van aanvragen, bijvoorbeeld bij omleidingen, verificatie, het genereren van koppelingen, beleidsevaluatie en clientgeolocatie.

Apps die zijn bedoeld om uitgevoerd te worden op een webfarm, zouden Host ASP.NET Core in een webfarmmoeten raadplegen.

Doorgestuurde headers

Standaard sturen proxy's informatie door in HTTP-headers.

Koptekst Beschrijving
X-Forwarded-For (XFF) Bevat informatie over de client die de aanvraag en volgende proxy's heeft geïnitieerd in een keten van proxy's. Deze parameter kan IP-adressen en, optioneel, poortnummers bevatten. In een keten van proxyservers geeft de eerste parameter de client aan waar de aanvraag voor het eerst is gedaan. Verdere proxy-id's volgen. De laatste proxy in de keten staat niet in de lijst met parameters. Het IP-adres van de laatste proxy en eventueel een poortnummer zijn beschikbaar als het externe IP-adres op de transportlaag.
X-Forwarded-Proto (XFP) De waarde van het oorspronkelijke schema, HTTP of HTTPS. De waarde kan ook een lijst met schema's zijn als de aanvraag meerdere proxy's heeft doorlopen.
X-Forwarded-Host (XFH) De oorspronkelijke waarde van het veld Hostheader. Meestal wijzigen proxy's de Host-header niet. Zie Microsoft Security Advisory CVE-2018-0787 voor informatie over een beveiligingsprobleem met uitbreiding van bevoegdheden dat van invloed is op systemen waarop de proxy hostheaders niet valideert of beperkt tot bekende goede waarden.
X-Forwarded-Prefix Het oorspronkelijke basispad dat door de client is aangevraagd. Deze header kan handig zijn voor toepassingen om URL's, omleidingen of koppelingen naar de client correct te genereren.

De Forwarded Headers Middleware, ForwardedHeadersMiddleware, leest deze headers en vult de bijbehorende velden op HttpContextin.

De middleware wordt bijgewerkt:

Zie dit GitHub-probleemvoor meer informatie over het voorgaande.

Middleware voor doorgestuurde headers standaardinstellingen kunnen worden geconfigureerd. Voor de standaardinstellingen:

  • Er is slechts één proxy tussen de app en de bron van de aanvragen.
  • Alleen loopback-adressen zijn geconfigureerd voor bekende proxy's en bekende netwerken.
  • De doorgestuurde headers hebben de naam X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host en X-Forwarded-Prefix.
  • De ForwardedHeaders waarde is ForwardedHeaders.None, de gewenste doorstuurservers moeten hier worden ingesteld om de middleware in te schakelen.

Niet alle netwerkapparaten voegen de X-Forwarded-For en X-Forwarded-Proto headers toe zonder extra configuratie. Raadpleeg de richtlijnen van de fabrikant van uw apparaat als opgegeven aanvragen deze headers niet bevatten wanneer ze de app bereiken. Als het apparaat andere headernamen gebruikt dan X-Forwarded-For en X-Forwarded-Proto, stelt u de ForwardedForHeaderName- en ForwardedProtoHeaderName-opties in zodat deze overeenkomen met de headernamen die door het apparaat worden gebruikt. Voor meer informatie, zie Opties voor doorgestuurde headers Middleware en Configuratie voor een proxy die gebruikmaakt van verschillende headernamen.

IIS/IIS Express en ASP.NET Core-module

Forwarded Headers Middleware is standaard ingeschakeld door IIS Integration Middleware wanneer de app wordt gehost buiten het proces achter IIS en de ASP.NET Core Module (ANCM) voor IIS. Doorgestuurde Headers Middleware wordt geactiveerd om als eerste te worden uitgevoerd in de middleware-pijplijn, met een beperkte configuratie die specifiek is voor de ASP.NET Core-module. De beperkte configuratie is te wijten aan vertrouwensproblemen met doorgestuurde headers, bijvoorbeeld IP-adresvervalsing. De middleware is geconfigureerd om de X-Forwarded-For en X-Forwarded-Proto headers door te sturen en is beperkt tot één localhost-proxy. Als er aanvullende configuratie is vereist, raadpleegt u de Opties voor doorgeschakelde headers middleware.

Andere scenario's voor proxyservers en load balancer

Buiten het gebruik van IIS-integratie bij het hosten van out-of-process, is Forwarded Headers Middleware niet standaard ingeschakeld. De middleware voor doorgestuurde headers moet zijn ingeschakeld voor een app voor het verwerken van doorgestuurde headers met UseForwardedHeaders. Nadat u de middleware hebt ingeschakeld en er geen ForwardedHeadersOptions zijn opgegeven voor de middleware, worden standaard ForwardedHeadersOptions.ForwardedHeaders ingesteld op ForwardedHeaders.None.

Configureer de middleware met ForwardedHeadersOptions om de X-Forwarded-For en X-Forwarded-Proto headers door te sturen.

Volgorde van doorgestuurde headers in middleware

Middleware voor doorgestuurde headers moet worden uitgevoerd voordat andere middleware. Deze volgorde zorgt ervoor dat de middleware die afhankelijk is van informatie over doorgestuurde headers de headerwaarden kan gebruiken voor verwerking. Doorgezonden Headers Middleware kan worden uitgevoerd na diagnoseprocessen en foutafhandeling, maar moet worden uitgevoerd voordat UseHstswordt aangeroepen.

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

U kunt ook UseForwardedHeaders aanroepen vóór diagnose.

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

Notitie

Als er geen ForwardedHeadersOptions worden opgegeven of rechtstreeks op de extensiemethode met UseForwardedHeadersworden toegepast, zijn de standaardheaders die worden doorgestuurd ForwardedHeaders.None. De eigenschap ForwardedHeaders moet worden geconfigureerd met de headers die doorgestuurd moeten worden.

Nginx-configuratie

Zie Host ASP.NET Core op Linux met Nginxom de headers voor X-Forwarded-For en X-Forwarded-Proto door te sturen. Zie voor meer informatie NGINX: de Forwarded-header gebruiken.

Apache-configuratie

X-Forwarded-For wordt automatisch toegevoegd. Voor meer informatie, zie Apache Module mod_proxy: Headers voor omgekeerde proxyaanvragen.

Middlewareopties voor doorgestuurde headers

ForwardedHeadersOptions het gedrag van de Forwarded Headers Middlewarecontroleren. In het volgende voorbeeld worden de standaardwaarden gewijzigd:

  • Beperkt het aantal vermeldingen in de doorgestuurde headers tot 2.
  • Hiermee wordt een bekend proxyadres van 127.0.10.1toegevoegd.
  • Hiermee wijzigt u de naam van de doorgestuurde koptekst van de standaard-X-Forwarded-For in 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();
Optie Beschrijving
AllowedHosts Hiermee beperkt u hosts door de X-Forwarded-Host header tot de opgegeven waarden.
  • Waarden worden vergeleken met ordinaal-ignore-case.
  • Poortnummers moeten worden uitgesloten.
  • Als de lijst leeg is, zijn alle hosts toegestaan.
  • Een jokerteken op het hoogste niveau * staat alle niet-lege hosts toe.
  • Jokertekens voor subdomeinen zijn toegestaan, maar komen niet overeen met het hoofddomein. *.contoso.com komt bijvoorbeeld overeen met het subdomein foo.contoso.com maar niet het hoofddomein contoso.com.
  • Unicode-hostnamen zijn toegestaan, maar worden geconverteerd naar Punycode- voor het vergelijken.
  • IPv6-adressen moeten begrenzingshaken bevatten en zich in conventionele vorm bevinden (bijvoorbeeld [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). IPv6-adressen zijn niet speciaal bedoeld om te controleren op logische gelijkheid tussen verschillende indelingen en er wordt geen canonicalisatie uitgevoerd.
  • Het niet beperken van de toegestane hosts kan een cyberaanvaller in staat stellen om links te vervalsen die door de service worden gegenereerd.
De standaardwaarde is een lege IList<string>.
ForwardedForHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de koptekst die is opgegeven door ForwardedHeadersDefaults.XForwardedForHeaderName. Deze optie wordt gebruikt wanneer de proxy/doorstuurserver de X-Forwarded-For header niet gebruikt, maar een andere header gebruikt om de informatie door te sturen.

De standaardwaarde is X-Forwarded-For.
ForwardedHeaders Hiermee wordt bepaald welke doorstuurders moeten worden verwerkt. Zie de ForwardedHeaders Enum- voor de lijst met velden die van toepassing zijn. Typische waarden die aan deze eigenschap zijn toegewezen, worden ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

De standaardwaarde is ForwardedHeaders.None.
ForwardedHostHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XForwardedHostHeaderName. Deze optie wordt gebruikt wanneer de proxy/doorstuurserver de X-Forwarded-Host header niet gebruikt, maar een andere header gebruikt om de informatie door te sturen.

De standaardwaarde is X-Forwarded-Host.
ForwardedProtoHeaderName Gebruik de header die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XForwardedProtoHeaderName. Deze optie wordt gebruikt wanneer de proxy/doorstuurserver de X-Forwarded-Proto header niet gebruikt, maar een andere header gebruikt om de informatie door te sturen.

De standaardwaarde is X-Forwarded-Proto.
ForwardLimit Hiermee beperkt u het aantal vermeldingen in de kopteksten die worden verwerkt. Ingesteld op null om de limiet uit te schakelen, maar dit moet alleen worden gedaan als KnownProxies of KnownNetworks zijn geconfigureerd. Het instellen van een niet-null waarde is een voorzorgsmaatregel (maar geen garantie) om te beschermen tegen onjuist geconfigureerde proxy's en schadelijke aanvragen die afkomstig zijn van side-channels in het netwerk.

Doorgeschakelde headers Middleware verwerkt headers in omgekeerde volgorde van rechts naar links. Als de standaardwaarde (1) wordt gebruikt, wordt alleen de meest rechtse waarde van de headers verwerkt, tenzij de waarde van ForwardLimit wordt verhoogd.

De standaardwaarde is 1.
KnownNetworks Adresbereiken van bekende netwerken waaruit doorgestuurde headers moeten worden geaccepteerd. Ip-bereiken opgeven met cidr-notatie (Classless Interdomain Routing).

Als de server sockets met dubbele modus gebruikt, worden IPv4-adressen opgegeven in een IPv6-indeling (bijvoorbeeld 10.0.0.1 in IPv4 die als ::ffff:10.0.0.1in IPv6 worden weergegeven). Zie IPAddress.MapToIPv6-. Bepaal of deze indeling is vereist door de HttpContext.Connection.RemoteIpAddresste bekijken.

De standaardwaarde is een IList<IPNetwork> met één vermelding voor new IPNetwork(IPAddress.Loopback, 8).
KnownProxies Adressen van bekende proxy's waaruit doorgestuurde headers moeten worden geaccepteerd. Gebruik KnownProxies om exacte IP-adresovereenkomsten op te geven.

Als de server sockets met dubbele modus gebruikt, worden IPv4-adressen opgegeven in een IPv6-indeling (bijvoorbeeld 10.0.0.1 in IPv4 die als ::ffff:10.0.0.1in IPv6 worden weergegeven). Zie IPAddress.MapToIPv6-. Bepaal of deze indeling is vereist door de HttpContext.Connection.RemoteIpAddresste bekijken.

De standaardwaarde is een IList<IPAddress> met één vermelding voor IPAddress.IPv6Loopback.
OriginalForHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XOriginalForHeaderName.

De standaardwaarde is X-Original-For.
OriginalHostHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XOriginalHostHeaderName.

De standaardwaarde is X-Original-Host.
OriginalProtoHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XOriginalProtoHeaderName.

De standaardwaarde is X-Original-Proto.
RequireHeaderSymmetry Zorg ervoor dat het aantal headerwaarden in overeenstemming is tussen de ForwardedHeadersOptions.ForwardedHeaders die worden verwerkt.

De standaardwaarde in ASP.NET Core 1.x is true. De standaardwaarde in ASP.NET Core 2.0 of hoger is false.

Scenarios en use cases

Wanneer het niet mogelijk is om doorgestuurde headers toe te voegen en alle aanvragen veilig zijn

In sommige gevallen is het misschien niet mogelijk om doorgestuurde headers toe te voegen aan de aanvragen die via proxy naar de app worden gestuurd. Als de proxy afdwingt dat alle openbare externe aanvragen HTTPS zijn, kan het schema handmatig worden ingesteld voordat u een willekeurig type middleware gebruikt:

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

Deze code kan worden uitgeschakeld met een omgevingsvariabele of andere configuratie-instelling in een ontwikkel- of faseringsomgeving:

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

Werken met padbasis en proxy's die het aanvraagpad wijzigen

Sommige proxy's geven het pad intact door, maar met een app-basispad dat moet worden verwijderd, zodat routering goed werkt. UsePathBaseExtensions.UsePathBase middleware splitst het pad in HttpRequest.Path en het basispad van de app in HttpRequest.PathBase.

Als /foo het basispad van de app is voor een proxypad dat als /foo/api/1wordt doorgegeven, stelt de middleware Request.PathBase in op /foo en Request.Path op /api/1 met de volgende opdracht:

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

Notitie

Wanneer u WebApplication gebruikt (zie Migreren van ASP.NET Core 5.0 naar 6.0), moet app.UseRouting na UsePathBase worden aangeroepen, zodat de routerings-middleware het gewijzigde pad kan observeren voordat overeenkomende routes worden gebruikt. Anders worden routes vergeleken voordat het pad wordt herschreven door UsePathBase zoals beschreven in de artikelen Middleware Ordering en Routing.

Het oorspronkelijke pad en de padbasis worden opnieuw toegepast wanneer de middleware opnieuw wordt aangeroepen in omgekeerde richting. Zie ASP.NET Core Middlewarevoor meer informatie over de verwerking van middlewareorders.

Als de proxy het pad trimt (bijvoorbeeld het doorsturen van /foo/api/1 naar /api/1), herstelt u omleidingen en koppelingen door de eigenschap PathBase van de aanvraag in te stellen:

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

Als de proxy padgegevens toevoegt, verwijdert u een deel van het pad om omleidingen en koppelingen op te lossen met behulp van StartsWithSegments en wijst u deze toe aan de eigenschap Path:

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

    return next(context);
});

Configuratie voor een proxy die gebruikmaakt van verschillende headernamen

Als de proxy geen headers gebruikt met de naam X-Forwarded-For en X-Forwarded-Proto om het proxyadres/de poort en de oorspronkelijke schemagegevens door te sturen, stelt u de opties voor ForwardedForHeaderName en ForwardedProtoHeaderName in zodat deze overeenkomen met de headernamen die door de proxy worden gebruikt:

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

Het schema doorsturen voor Linux- en niet-IIS-reverse proxy's

Apps die UseHttpsRedirection aanroepen en UseHsts een site in een oneindige lus plaatsen als deze worden geïmplementeerd op een Azure Linux App Service, virtuele Azure Linux-machine (VM) of achter een andere omgekeerde proxy dan IIS. TLS wordt beëindigd door de omgekeerde proxy en Kestrel wordt niet op de hoogte gesteld van het juiste aanvraagschema. OAuth en OIDC mislukken ook in deze configuratie omdat ze onjuiste omleidingen genereren. UseIISIntegration voegt Forwarded Headers-middleware toe en configureert deze bij het uitvoeren achter IIS, maar is er geen overeenkomstige automatische configuratie voor Linux (Apache- of Nginx-integratie).

Als u het schema wilt doorsturen vanuit de proxy in niet-IIS-scenario's, schakelt u de Forwarded Headers-middleware in door ASPNETCORE_FORWARDEDHEADERS_ENABLED in te stellen op true. Waarschuwing: deze vlag maakt gebruik van instellingen die zijn ontworpen voor cloudomgevingen en schakelt functies zoals de KnownProxies option niet in om te beperken vanaf welke IP-doorstuurservers worden geaccepteerd.

Certificaat doorsturen

Azuur

Zie Wederzijdse TLS-verificatie configureren voor Azure App Serviceom Azure App Service te configureren voor het doorsturen van certificaten. De volgende richtlijnen hebben betrekking op het configureren van de ASP.NET Core-app.

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

Andere webproxy's

Als een proxy wordt gebruikt die niet IIS of ARR (Application Request Routing) van Azure App Service is, configureert u de proxy om het certificaat dat is ontvangen in een HTTP-header door te sturen.

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

Als de proxy het certificaat niet base64-codeert, zoals bij Nginx het geval is, zet de optie HeaderConverter aan. Bekijk het volgende voorbeeld:

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

Problemen oplossen

Wanneer headers niet worden doorgestuurd zoals verwacht, schakelt u debug niveau in logboekregistratie en logboekregistratie van HTTP-aanvragen. UseHttpLogging moet na UseForwardedHeadersworden aangeroepen:

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

Als er meerdere waarden in een bepaalde header staan, verwerkt de Forwarded Headers Middleware headers in omgekeerde volgorde van rechts naar links. De standaard ForwardLimit is 1 (één), dus alleen de meest rechtse waarde uit de headers wordt verwerkt, tenzij de waarde van ForwardLimit wordt verhoogd.

Het oorspronkelijke externe IP-adres van de aanvraag moet overeenkomen met een vermelding in de KnownProxies of KnownNetworks lijsten voordat doorgestuurde headers worden verwerkt. Hierdoor wordt adresvervalsing van headers beperkt door doorstuurservers van niet-vertrouwde proxy's niet te accepteren. Wanneer een onbekende proxy wordt gedetecteerd, geeft logboekregistratie het adres van de proxy aan:

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

In het voorgaande voorbeeld is 10.0.0.100 een proxyserver. Als de server een vertrouwde proxy is, voegt u het IP-adres van de server toe aan KnownProxiesof voegt u een vertrouwd netwerk toe aan KnownNetworks. Zie voor meer informatie de sectie Doorgeschakelde Headers Middleware-opties.

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

Als u de logboeken wilt weergeven, voegt u "Microsoft.AspNetCore.HttpLogging": "Information" toe aan het appsettings.Development.json-bestand:

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

Belangrijk

Alleen vertrouwde proxy's en netwerken toestaan headers door te sturen. Anders zijn IP-spoofing-aanvallen mogelijk.

Aanvullende informatiebronnen

In de aanbevolen configuratie voor ASP.NET Core wordt de app gehost met behulp van IIS/ASP.NET Core Module, Nginx of Apache. Proxyservers, load balancers en andere netwerkapparaten verhullen vaak informatie over de aanvraag voordat deze de app bereikt:

  • Wanneer HTTPS-aanvragen via HTTP worden geproxied, gaat het oorspronkelijke schema (HTTPS) verloren en moet het worden doorgestuurd in een header.
  • Omdat een app een aanvraag van de proxy ontvangt en niet de werkelijke bron op internet of het bedrijfsnetwerk, moet het ip-adres van de oorspronkelijke client ook worden doorgestuurd in een header.

Deze informatie kan belangrijk zijn bij het verwerken van aanvragen, bijvoorbeeld bij omleidingen, verificatie, het genereren van koppelingen, beleidsevaluatie en clientgeolocatie.

Doorgestuurde headers

Standaard sturen proxy's informatie door in HTTP-headers.

Koptekst Beschrijving
X-Forwarded-For Bevat informatie over de client die de aanvraag en volgende proxy's heeft geïnitieerd in een keten van proxy's. Deze parameter kan IP-adressen bevatten (en, optioneel, poortnummers). In een keten van proxyservers geeft de eerste parameter de client aan waar de aanvraag voor het eerst is gedaan. De volgende proxy-identificatiecodes komen eraan. De laatste proxy in de keten staat niet in de lijst met parameters. Het IP-adres van de laatste proxy en eventueel een poortnummer zijn beschikbaar als het externe IP-adres op de transportlaag.
X-Forwarded-Proto De waarde van het oorspronkelijke schema (HTTP/HTTPS). De waarde kan ook een lijst met schema's zijn als de aanvraag meerdere proxy's heeft doorlopen.
X-Forwarded-Host De oorspronkelijke waarde van het veld Hostheader. Meestal wijzigen proxy's de Host-header niet. Zie Microsoft Security Advisory CVE-2018-0787 voor informatie over een beveiligingsprobleem met uitbreiding van bevoegdheden dat van invloed is op systemen waarop de proxy hostheaders niet valideert of beperkt tot bekende goede waarden.

De Middleware voor doorgeschakelde headers (ForwardedHeadersMiddleware) leest deze headers en vult de bijbehorende velden in op HttpContext.

De middleware wordt bijgewerkt:

  • HttpContext.Connection.RemoteIpAddress: Instellen met behulp van de waarde van de X-Forwarded-For-header. Aanvullende instellingen beïnvloeden hoe de middleware RemoteIpAddressinstelt. Zie de opties Forwarded Headers Middlewarevoor meer informatie. De verbruikte waarden worden verwijderd uit X-Forwarded-Foren de oude waarden blijven behouden in X-Original-For. Hetzelfde patroon wordt toegepast op de andere headers, Host en Proto.
  • HttpContext.Request.Scheme: Instellen met behulp van de X-Forwarded-Proto headerwaarde.
  • HttpContext.Request.Host-: Instellen met behulp van de waarde van de X-Forwarded-Host-header.

Zie dit GitHub-probleemvoor meer informatie over het voorgaande.

Middleware voor doorgestuurde headers standaardinstellingen kunnen worden geconfigureerd. Voor de standaardinstellingen:

  • Er is slechts één proxy tussen de app en de bron van de aanvragen.
  • Alleen loopback-adressen zijn geconfigureerd voor bekende proxy's en bekende netwerken.
  • De doorgestuurde headers hebben de naam X-Forwarded-For en X-Forwarded-Proto.
  • De ForwardedHeaders waarde is ForwardedHeaders.None, de gewenste doorstuurservers moeten hier worden ingesteld om de middleware in te schakelen.

Niet alle netwerkapparaten voegen de X-Forwarded-For en X-Forwarded-Proto headers toe zonder extra configuratie. Raadpleeg de richtlijnen van de fabrikant van uw apparaat als opgegeven aanvragen deze headers niet bevatten wanneer ze de app bereiken. Als het apparaat andere headernamen gebruikt dan X-Forwarded-For en X-Forwarded-Proto, stelt u de ForwardedForHeaderName- en ForwardedProtoHeaderName-opties in zodat deze overeenkomen met de headernamen die door het apparaat worden gebruikt. Voor meer informatie, zie Opties voor Doorgeschakelde Headers Middleware en Configuratie voor een proxy die verschillende headernamen gebruikt.

IIS/IIS Express en ASP.NET Core Module

Forwarded Headers Middleware is standaard ingeschakeld door IIS Integration Middleware wanneer de app wordt gehost out-of-process achter IIS en de ASP.NET Core Module. Doorgestuurde Headers Middleware wordt ingeschakeld om als eerste in de middleware-pijplijn te draaien met een beperkte configuratie, specifiek voor de ASP.NET Core Module, vanwege vertrouwensproblemen met doorgestuurde headers (zoals IP-adresvervalsing). De middleware is geconfigureerd om de X-Forwarded-For en X-Forwarded-Proto headers door te sturen en is beperkt tot één localhost-proxy. Als er aanvullende configuratie is vereist, raadpleegt u de Opties voor doorgeschakelde headers middleware.

Andere scenario's voor proxyservers en load balancer

Buiten het gebruik van IIS Integration bij het hosten van out-of-process, is de Forwarded Headers Middleware standaard niet ingeschakeld. De middleware voor doorgestuurde headers moet zijn ingeschakeld voor een app voor het verwerken van doorgestuurde headers met UseForwardedHeaders. Nadat u de middleware hebt ingeschakeld, indien geen ForwardedHeadersOptions voor de middleware zijn opgegeven, worden standaard de ForwardedHeadersOptions.ForwardedHeaders ingesteld op ForwardedHeaders.None.

Configureer de middleware met ForwardedHeadersOptions om de X-Forwarded-For en X-Forwarded-Proto headers in Startup.ConfigureServicesdoor te sturen.

De volgorde van doorgestuurde headers in middleware

Forwarded Headers Middleware moet worden uitgevoerd voordat andere middleware. Deze volgorde zorgt ervoor dat de middleware die afhankelijk is van informatie over doorgestuurde headers de headerwaarden kan gebruiken voor verwerking. Doorstuurde Headers Middleware kan na diagnostiek en foutafhandeling worden uitgevoerd, maar moet worden uitgevoerd voordat UseHstswordt aangeroepen.

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

U kunt ook UseForwardedHeaders aanroepen vóór diagnostiek.

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

Notitie

Als er geen ForwardedHeadersOptions zijn opgegeven in Startup.ConfigureServices of rechtstreeks bij de extensiemethode met UseForwardedHeaders, worden de standaardheaders die moeten worden doorgestuurd ForwardedHeaders.None. De ForwardedHeaders-eigenschap moet worden geconfigureerd met de headers die doorgestuurd moeten worden.

Nginx-configuratie

Zie Host ASP.NET Core op Linux met Nginxom de headers voor X-Forwarded-For en X-Forwarded-Proto door te sturen. Voor meer informatie, zie NGINX: Gebruik de doorgestuurde header.

Apache-configuratie

X-Forwarded-For wordt automatisch toegevoegd (zie Apache Module mod_proxy: Headers voor omgekeerde proxyaanvragen).

Middlewareopties voor doorgestuurde headers

ForwardedHeadersOptions het gedrag van de Middleware voor Doorgeschakelde Headers beheren. In het volgende voorbeeld worden de standaardwaarden gewijzigd:

  • Beperk het aantal vermeldingen in de doorgestuurde headers tot 2.
  • Voeg een bekend proxyadres van 127.0.10.1toe.
  • Wijzig de naam van de doorgestuurde header van de standaard-X-Forwarded-For in 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";
});
Optie Beschrijving
AllowedHosts Hiermee beperkt u hosts door de X-Forwarded-Host header tot de opgegeven waarden.
  • Waarden worden vergeleken met ordinaal-ignore-case.
  • Poortnummers moeten worden uitgesloten.
  • Als de lijst leeg is, zijn alle hosts toegestaan.
  • Een jokerteken op het hoogste niveau * staat alle niet-lege hosts toe.
  • Jokertekens voor subdomeinen zijn toegestaan, maar komen niet overeen met het hoofddomein. *.contoso.com komt bijvoorbeeld overeen met het subdomein foo.contoso.com maar niet het hoofddomein contoso.com.
  • Unicode-hostnamen zijn toegestaan, maar worden geconverteerd naar Punycode voor overeenkoming.
  • IPv6-adressen moeten begrenzingshaken bevatten en zich in conventionele vorm bevinden (bijvoorbeeld [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). IPv6-adressen zijn niet speciaal bedoeld om te controleren op logische gelijkheid tussen verschillende indelingen en er wordt geen canonicalisatie uitgevoerd.
  • Als de toegestane hosts niet worden beperkt, kan een cyberaanvaller de door de service gegenereerde koppelingen spoofen.
De standaardwaarde is een lege IList<string>.
ForwardedHeaders Hiermee wordt aangegeven welke doorstuurservers moeten worden verwerkt. Zie de ForwardedHeaders Enum- voor de lijst met velden die van toepassing zijn. Typische waarden die aan deze eigenschap zijn toegewezen, worden ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

De standaardwaarde is ForwardedHeaders.None.
ForwardedForHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de koptekst die is opgegeven door ForwardedHeadersDefaults.XForwardedForHeaderName. Deze optie wordt gebruikt wanneer de proxy/doorstuurserver de X-Forwarded-For header niet gebruikt, maar een andere header gebruikt om de informatie door te sturen.

De standaardwaarde is X-Forwarded-For.
ForwardedHostHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XForwardedHostHeaderName. Deze optie wordt gebruikt wanneer de proxy/doorstuurserver de X-Forwarded-Host header niet gebruikt, maar een andere header gebruikt om de informatie door te sturen.

De standaardwaarde is X-Forwarded-Host.
ForwardedProtoHeaderName Gebruik de header die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XForwardedProtoHeaderName. Deze optie wordt gebruikt wanneer de proxy/doorstuurserver de X-Forwarded-Proto header niet gebruikt, maar een andere header gebruikt om de informatie door te sturen.

De standaardwaarde is X-Forwarded-Proto.
ForwardedPrefixHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XForwardedPrefixHeaderName. Deze optie wordt gebruikt wanneer de proxy/doorstuurserver de X-Forwarded-Prefix header niet gebruikt, maar een andere header gebruikt om de informatie door te sturen.

De standaardwaarde is X-Forwarded-Prefix.
ForwardLimit Hiermee beperkt u het aantal vermeldingen in de kopteksten die worden verwerkt. Ingesteld op null om de limiet uit te schakelen, maar dit moet alleen worden gedaan als KnownProxies of KnownNetworks zijn geconfigureerd. Het instellen van een niet-null waarde is een voorzorgsmaatregel (maar geen garantie) om te beschermen tegen onjuist geconfigureerde proxy's en schadelijke aanvragen die afkomstig zijn van side-channels in het netwerk.

De Middleware voor doorgeschakelde kopteksten verwerkt kopteksten in omgekeerde volgorde van rechts naar links. Als de standaardwaarde (1) wordt gebruikt, wordt alleen de meest rechtse waarde van de headers verwerkt, tenzij de waarde van ForwardLimit wordt verhoogd.

De standaardwaarde is 1.
KnownNetworks Adresbereiken van bekende netwerken waaruit doorgestuurde headers moeten worden geaccepteerd. Ip-bereiken opgeven met cidr-notatie (Classless Interdomain Routing).

Als de server sockets met dubbele modus gebruikt, worden IPv4-adressen opgegeven in een IPv6-indeling (bijvoorbeeld 10.0.0.1 in IPv4 die als ::ffff:10.0.0.1in IPv6 worden weergegeven). Zie IPAddress.MapToIPv6-. Bepaal of deze indeling is vereist door de HttpContext.Connection.RemoteIpAddresste bekijken.

De standaardwaarde is een IList<IPNetwork> met één vermelding voor new IPNetwork(IPAddress.Loopback, 8).
KnownProxies Adressen van bekende proxy's waaruit doorgestuurde headers moeten worden geaccepteerd. Gebruik KnownProxies om exacte IP-adresovereenkomsten op te geven.

Als de server sockets met dubbele modus gebruikt, worden IPv4-adressen opgegeven in een IPv6-indeling (bijvoorbeeld 10.0.0.1 in IPv4 die als ::ffff:10.0.0.1in IPv6 worden weergegeven). Zie IPAddress.MapToIPv6-. Bepaal of deze indeling is vereist door de HttpContext.Connection.RemoteIpAddresste bekijken.

De standaardwaarde is een IList<IPAddress> met één vermelding voor IPAddress.IPv6Loopback.
OriginalForHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XOriginalForHeaderName.

De standaardwaarde is X-Original-For.
OriginalHostHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XOriginalHostHeaderName.

De standaardwaarde is X-Original-Host.
OriginalProtoHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XOriginalProtoHeaderName.

De standaardwaarde is X-Original-Proto.
OriginalPrefixHeaderName Gebruik de koptekst die is opgegeven door deze eigenschap in plaats van de header die is opgegeven door ForwardedHeadersDefaults.XOriginalPrefixHeaderName.

De standaardwaarde is X-Original-Prefix.
RequireHeaderSymmetry Zorg ervoor dat het aantal headerwaarden in sync zijn tussen de ForwardedHeadersOptions.ForwardedHeaders die worden verwerkt.

De standaardwaarde in ASP.NET Core 1.x is true. De standaardwaarde in ASP.NET Core 2.0 of hoger is false.

Scenarios en gebruiksscenario's

Wanneer het niet mogelijk is om doorgestuurde headers toe te voegen en alle aanvragen veilig zijn

In sommige gevallen is het misschien niet mogelijk om doorgestuurde headers toe te voegen aan de verzoeken die naar de app worden doorgeleid. Als de proxy afdwingt dat alle openbare externe aanvragen HTTPS zijn, kan het schema handmatig worden ingesteld in Startup.Configure voordat u een willekeurig type middleware gebruikt:

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

Deze code kan worden uitgeschakeld met een omgevingsvariabele of andere configuratie-instelling in een ontwikkel- of faseringsomgeving.

Omgaan met padbasis en proxy's die het aanvraagpad wijzigen

Sommige proxy's geven het pad intact door, maar met een app-basispad dat moet worden verwijderd, zodat routering goed werkt. UsePathBaseExtensions.UsePathBase middleware splitst het pad in HttpRequest.Path en het basispad van de app in HttpRequest.PathBase.

Als /foo het basispad van de app is voor een proxypad dat als /foo/api/1wordt doorgegeven, stelt de middleware Request.PathBase in op /foo en Request.Path op /api/1 met de volgende opdracht:

app.UsePathBase("/foo");

Het oorspronkelijke pad en de padbasis worden opnieuw toegepast wanneer de middleware opnieuw wordt aangeroepen in omgekeerde richting. Zie ASP.NET Core Middlewarevoor meer informatie over de verwerking van middlewareorders.

Als de proxy het pad trimt (bijvoorbeeld het doorsturen van /foo/api/1 naar /api/1), herstelt u omleidingen en koppelingen door de eigenschap PathBase van de aanvraag in te stellen:

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

Als de proxy padgegevens toevoegt, verwijdert u een deel van het pad om omleidingen en koppelingen op te lossen met behulp van StartsWithSegments en wijst u deze toe aan de eigenschap Path:

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

    return next();
});

Configuratie voor een proxy die gebruikmaakt van verschillende headernamen

Als de proxy geen headers gebruikt met de naam X-Forwarded-For en X-Forwarded-Proto om het proxyadres/de poort en de oorspronkelijke schemagegevens door te sturen, stelt u de opties voor ForwardedForHeaderName en ForwardedProtoHeaderName in zodat deze overeenkomen met de headernamen die door de proxy worden gebruikt:

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

Het schema doorsturen voor Linux- en niet-IIS-reverse proxy's

Apps die UseHttpsRedirection aanroepen en UseHsts een site in een oneindige lus plaatsen als deze worden geïmplementeerd op een Azure Linux App Service, virtuele Azure Linux-machine (VM) of achter een andere omgekeerde proxy dan IIS. TLS wordt beëindigd door de omgekeerde proxy en Kestrel wordt niet op de hoogte gesteld van het juiste aanvraagschema. OAuth en OIDC mislukken ook in deze configuratie omdat ze onjuiste omleidingen genereren. UseIISIntegration voegt Middleware voor doorgestuurde headers toe en configureert deze bij uitvoering achter IIS, maar er is geen passende automatische configuratie voor Linux (Apache- of Nginx-integratie).

Als u het schema wilt doorsturen vanuit de proxy in niet-IIS-scenario's, voegt u Forwarded Headers Middleware toe en configureert u deze. Gebruik in Startup.ConfigureServicesde volgende 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();
    });
}

Certificaat doorsturen

Azuur

Zie Wederzijdse TLS-verificatie configureren voor Azure App Serviceom Azure App Service te configureren voor het doorsturen van certificaten. De volgende richtlijnen hebben betrekking op het configureren van de ASP.NET Core-app.

Voeg in Startup.Configurede volgende code toe voordat de aanroep naar app.UseAuthentication();:

app.UseCertificateForwarding();

Configureer Certificate Forwarding Middleware om de headernaam op te geven die door Azure wordt gebruikt. Voeg in Startup.ConfigureServicesde volgende code toe om de header te configureren waaruit de middleware een certificaat bouwt:

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

Andere webproxy's

Als een proxy wordt gebruikt die niet IIS of ARR (Application Request Routing) van Azure App Service is, configureert u de proxy om het certificaat dat is ontvangen in een HTTP-header door te sturen. Voeg in Startup.Configurede volgende code toe voordat de aanroep naar app.UseAuthentication();:

app.UseCertificateForwarding();

Configureer de Middleware voor het doorsturen van certificaten om de naam van de header op te geven. Voeg in Startup.ConfigureServicesde volgende code toe om de header te configureren waaruit de middleware een certificaat bouwt:

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

Als de proxy het certificaat niet base64-codeert (zoals het geval is met Nginx), stelt u de optie HeaderConverter in. Bekijk het volgende voorbeeld 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;
    }
});

Problemen oplossen

Wanneer headers niet worden doorgestuurd zoals verwacht, schakelt u logboekregistratie in. Als de logboeken onvoldoende informatie bevatten om het probleem op te lossen, inventariseert u de aanvraagheaders die door de server zijn ontvangen. Gebruik inline-middleware om aanvraagheaders naar een app-antwoord te schrijven of de headers te registreren.

Als u de headers naar het antwoord van de app wilt schrijven, plaatst u de volgende terminal inline-middleware direct na de aanroep naar 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}");
});

U kunt naar logboeken schrijven in plaats van de hoofdtekst van het antwoord. Door naar logboeken te schrijven, kan de site normaal functioneren tijdens het debuggen.

Logboeken schrijven in plaats van naar de hoofdtekst van het antwoord:

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

Wanneer deze worden verwerkt, worden X-Forwarded-{For|Proto|Host|Prefix} waarden verplaatst naar X-Original-{For|Proto|Host|Prefix}. Als er meerdere waarden in een bepaalde header staan, verwerkt de Forwarded Headers-middleware de headers in omgekeerde volgorde van rechts naar links. De standaard ForwardLimit is 1 (één), dus alleen de meest rechtse waarde uit de headers wordt verwerkt, tenzij de waarde van ForwardLimit wordt verhoogd.

Het oorspronkelijke externe IP-adres van de aanvraag moet overeenkomen met een vermelding in de KnownProxies of KnownNetworks lijsten voordat doorgestuurde headers worden verwerkt. Hierdoor wordt adresvervalsing van headers beperkt door doorstuurservers van niet-vertrouwde proxy's niet te accepteren. Wanneer een onbekende proxy wordt gedetecteerd, geeft logboekregistratie het adres van de proxy aan:

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

In het voorgaande voorbeeld is 10.0.0.100 een proxyserver. Als de server een vertrouwde proxy is, voegt u het IP-adres van de server toe aan KnownProxies (of voegt u een vertrouwd netwerk toe aan KnownNetworks) in Startup.ConfigureServices. Zie de sectie Doorgeschakelde headers Middleware-opties voor meer informatie.

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

Belangrijk

Alleen vertrouwde proxy's en netwerken toestaan headers door te sturen. Anders zijn IP-adresvervalsing aanvallen mogelijk.

Aanvullende informatiebronnen