Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Notitie
Dit is niet de nieuwste versie van dit artikel. Zie de .NET 10-versie van dit artikel voor 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 10-versie van dit artikel voor 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 Beveiliging 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 middleware voor doorgestuurde headers, ForwardedHeadersMiddleware leest deze headers en vult de bijbehorende velden van HttpContext in.
De middleware wordt bijgewerkt:
-
HttpContext.Connection.RemoteIpAddress: Instellen met behulp van deX-Forwarded-Forheader-waarde. Aanvullende instellingen beïnvloeden hoe de middlewareRemoteIpAddressinstelt. Zie de middlewareopties voor doorgestuurde headers voor meer informatie. De verbruikte waarden worden verwijderd uitX-Forwarded-Foren de oude waarde vanHttpContext.Connection.RemoteIpAddresswordt inX-Original-Forbehouden. Opmerking: dit proces kan meerdere keren worden herhaald als er meerdere waarden zijnX-Forwarded-For/Proto/Host/Prefix, wat resulteert in verschillende waarden die zijn verplaatst naarX-Original-*, inclusief het origineelRemoteIpAddress/Host/Scheme/PathBase. -
HttpContext.Request.Scheme: Instellen met behulp van deX-Forwarded-Protoheader-waarde. De verbruikte waarde wordt verwijderd uitX-Forwarded-Protoen de oude waarde vanHttpContext.Request.Schemeblijft behouden inX-Original-Proto. -
HttpContext.Request.Host: Instellen met behulp van deX-Forwarded-Hostheader-waarde. De verbruikte waarde wordt verwijderd uitX-Forwarded-Hosten de oude waarde vanHttpContext.Request.Hostblijft behouden inX-Original-Host. -
HttpContext.Request.PathBase: Instellen met behulp van deX-Forwarded-Prefixheader-waarde. De verbruikte waarde wordt verwijderd uitX-Forwarded-Prefixen de oude waarde vanHttpContext.Request.PathBaseblijft behouden inX-Original-Prefix.
Zie dit GitHub-probleemvoor meer informatie over het voorgaande.
De standaardinstellingen van de middleware voor doorgestuurde headers 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-HostenX-Forwarded-Prefix. - De
ForwardedHeaderswaarde 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. Zie de opties voor doorgestuurde headers middleware en configuratie voor een proxy die gebruikmaakt van verschillende headernamen voor meer informatie.
IIS/IIS Express en ASP.NET Core-module
De IIS-integratiemiddleware schakelt standaard de middleware voor doorgestuurde headers in wanneer de app buiten het proces wordt gehost achter IIS en de ASP.NET Core Module (ANCM) voor IIS. Middleware voor doorgestuurde headers wordt geactiveerd zodat deze als eerste in de middlewarepijplijn wordt uitgevoerd, 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 extra configuratie vereist is, zie de middlewareopties voor doorgestuurde headers.
Andere scenario's voor proxyservers en load balancer
Buiten het gebruik van IIS-integratie bij het hosten van out-of-process is doorgestuurde headers middleware niet standaard ingeschakeld. 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 middleware voor doorgestuurde headers
Middleware voor doorgestuurde headers moet worden uitgevoerd vóór andere middleware. Deze volgorde zorgt ervoor dat de middleware die afhankelijk is van informatie over doorgestuurde headers de headerwaarden kan gebruiken voor verwerking. De middleware voor doorgestuurde headers kan worden uitgevoerd na diagnose en foutafhandeling, maar moet worden uitgevoerd voordat UseHsts wordt 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 X-Forwarded-Forom de headers voor X-Forwarded-Proto en door te sturen.
Apache-configuratie
X-Forwarded-For wordt automatisch toegevoegd. Voor meer informatie, zie Apache Module mod_proxy: Headers voor omgekeerde proxyaanvragen.
Opties voor middleware voor doorgestuurde headers
ForwardedHeadersOptions het gedrag van de middleware voor doorgestuurde headers beheren. 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-ForinX-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.Middleware voor doorgestuurde headers verwerkt de 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 in .NET 5 naar .NET 6), moet app.UseRouting worden aangeroepen na UsePathBase, zodat de middleware voor routering het gewijzigde pad kan observeren voordat overeenkomende routes worden gezocht. Anders worden routes vergeleken voordat UsePathBase het pad opnieuw wordt geschreven, zoals beschreven in ASP.NET Core middleware en routering in ASP.NET Core.
Het oorspronkelijke pad en de padbasis worden opnieuw toegepast wanneer de middleware opnieuw wordt aangeroepen in omgekeerde richting. Zie ASP.NET Core middleware voor meer informatie over de verwerkingsvolgorde van middleware.
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. De omgekeerde proxy beëindigt TLS 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 wanneer deze achter IIS wordt uitgevoerd, maar er is geen vergelijkbare automatische configuratie voor Linux (Apache- of Nginx-integratie).
Als u in niet-IIS-scenario's het protocol via de proxy wilt doorsturen, 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 middleware voor het doorsturen van certificaten om de headernaam 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 KnownProxiesof voegt u een vertrouwd netwerk toe aan KnownNetworks. Zie de sectie middlewareopties voor doorgestuurde headers voor meer informatie.
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. 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 | 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 Beveiliging 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 doorgestuurde headers (ForwardedHeadersMiddleware) leest deze headers en vult de bijbehorende velden op HttpContext in.
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 middlewareRemoteIpAddressinstelt. Zie de middlewareopties voor doorgestuurde headers voor meer informatie. De verbruikte waarden worden verwijderd uitX-Forwarded-Foren de oude waarden blijven behouden inX-Original-For. Hetzelfde patroon wordt toegepast op de andere headers,HostenProto. -
HttpContext.Request.Scheme: Instellen met behulp van de
X-Forwarded-Protoheaderwaarde. -
HttpContext.Request.Host-: Instellen met behulp van de waarde van de
X-Forwarded-Host-header.
Zie dit GitHub-probleemvoor meer informatie over het voorgaande.
De standaardinstellingen van de middleware voor doorgestuurde headers 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-ForenX-Forwarded-Proto. - De
ForwardedHeaderswaarde 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. Zie de middlewareopties voor doorgestuurde headers en configuratie voor een proxy die gebruikmaakt van verschillende headernamen voor meer informatie.
IIS/IIS Express en ASP.NET Core-module
IIS-integratiemiddleware schakelt standaard middleware voor doorgestuurde headers in wanneer de app out-of-process wordt gehost achter IIS en de ASP.NET Core Module. Middleware voor doorgestuurde headers wordt geactiveerd zodat deze als eerste wordt uitgevoerd in de middlewarepijplijn, met een beperkte configuratie die specifiek is voor de ASP.NET Core-module vanwege zorgen over het vertrouwen in doorgestuurde headers (bijvoorbeeld IP-spoofing). 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 aanvullende configuratie nodig is, raadpleeg dan de opties voor de middleware voor doorgestuurde headers.
Andere scenario's voor proxyservers en load balancer
Buiten het gebruik van IIS-integratie bij het hosten van out-of-process is doorgestuurde headers middleware niet standaard ingeschakeld. 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 in Startup.ConfigureServicesdoor te sturen.
Volgorde van de middleware voor doorgestuurde headers
Middleware voor doorgestuurde headers moet worden uitgevoerd voordat andere middleware wordt uitgevoerd. Deze volgorde zorgt ervoor dat de middleware die afhankelijk is van informatie over doorgestuurde headers de headerwaarden kan gebruiken voor verwerking. De middleware voor doorgestuurde headers 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 diagnose.
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 eigenschap ForwardedHeaders moet worden geconfigureerd met de headers die doorgestuurd moeten worden.
Nginx-configuratie
Zie X-Forwarded-Forom de headers voor X-Forwarded-Proto en door te sturen.
Apache-configuratie
X-Forwarded-For wordt automatisch toegevoegd (zie Apache Module mod_proxy: Headers voor omgekeerde proxyaanvragen).
Opties voor doorgestuurde headers-middleware
ForwardedHeadersOptions het gedrag van de middleware voor doorgestuurde headers bepalen. 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-ForinX-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 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. |
| 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 Forwarded Headers verwerkt de 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. |
| 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 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 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 middleware voor meer informatie over de verwerkingsvolgorde van middleware.
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. De omgekeerde proxy beëindigt TLS 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 wanneer deze achter IIS wordt uitgevoerd, maar er is geen vergelijkbare automatische configuratie voor Linux (integratie met Apache of Nginx).
Als u het schema vanuit de proxy wilt doorsturen in niet-IIS-scenario's, voegt u doorgestuurde 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 middleware voor het doorsturen van certificaten om de headernaam op te geven die Azure 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 headernaam 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:
- Injecteer
ILogger<Startup>in deStartupklasse zoals beschreven in Logboekberichten maken. - 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 middleware voor doorgestuurde headers 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 middlewareopties voor doorgestuurde headers 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-spoofing-aanvallen mogelijk.