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:
-
HttpContext.Connection.RemoteIpAddress
: Instellen met behulp van deX-Forwarded-For
header-waarde. Aanvullende instellingen beïnvloeden hoe de middlewareRemoteIpAddress
instelt. Zie de opties Forwarded Headers Middlewarevoor meer informatie. De verbruikte waarden worden verwijderd uitX-Forwarded-For
en de oude waarde vanHttpContext.Connection.RemoteIpAddress
wordt inX-Original-For
behouden. Opmerking: dit proces kan meerdere keren worden herhaald als er meerdere waarden inX-Forwarded-For/Proto/Host/Prefix
zijn, wat resulteert in verschillende waarden die naarX-Original-*
zijn verplaatst, inclusief de oorspronkelijkeRemoteIpAddress/Host/Scheme/PathBase
. -
HttpContext.Request.Scheme
: Instellen met behulp van deX-Forwarded-Proto
header-waarde. De verbruikte waarde wordt verwijderd uitX-Forwarded-Proto
en de oude waarde vanHttpContext.Request.Scheme
blijft behouden inX-Original-Proto
. -
HttpContext.Request.Host
: Kan worden ingesteld met behulp van deX-Forwarded-Host
header-waarde. De verbruikte waarde wordt verwijderd uitX-Forwarded-Host
en de oude waarde vanHttpContext.Request.Host
blijft behouden inX-Original-Host
. -
HttpContext.Request.PathBase
: Instellen met behulp van de waarde in deX-Forwarded-Prefix
-header. De verbruikte waarde wordt verwijderd uitX-Forwarded-Prefix
en de oude waarde vanHttpContext.Request.PathBase
blijft behouden inX-Original-Prefix
.
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
enX-Forwarded-Prefix
. - De
ForwardedHeaders
waarde isForwardedHeaders.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.1
toegevoegd. - Hiermee wijzigt u de naam van de doorgestuurde koptekst van de standaard-
X-Forwarded-For
inX-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.
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.1 in 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.1 in 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/1
wordt 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.
- Configureer Certificaat-Doormiddelware om de header-naam op te geven die Azure gebruikt. Voeg de volgende code toe om de header te configureren waaruit de middleware een certificaat bouwt.
- Bel UseCertificateForwarding voordat de oproep naar UseAuthentication.
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.
- Configureer Middleware voor het doorsturen van certificaten om de headernaam op te geven. Voeg de volgende code toe om de header te configureren waaruit de middleware een certificaat bouwt.
- Bel UseCertificateForwarding voordat de oproep naar UseAuthentication.
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 KnownProxies
of 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 middlewareRemoteIpAddress
instelt. Zie de opties Forwarded Headers Middlewarevoor meer informatie. De verbruikte waarden worden verwijderd uitX-Forwarded-For
en de oude waarden blijven behouden inX-Original-For
. Hetzelfde patroon wordt toegepast op de andere headers,Host
enProto
. -
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
enX-Forwarded-Proto
. - De
ForwardedHeaders
waarde isForwardedHeaders.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.ConfigureServices
door 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 UseHsts
wordt 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.1
toe. - Wijzig de naam van de doorgestuurde header van de standaard-
X-Forwarded-For
inX-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.
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.1 in 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.1 in 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/1
wordt 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.ConfigureServices
de 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.Configure
de 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.ConfigureServices
de 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.Configure
de 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.ConfigureServices
de 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:
- Injecteer
ILogger<Startup>
in de klasseStartup
zoals beschreven in . Maak logboeken aan in de opstartfase. - Plaats de volgende inline middleware direct na het aanroepen van UseForwardedHeaders in
Startup.Configure
.
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.