Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.
Advertência
Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 10 deste artigo.
Por Chris Ross
Na configuração recomendada para o ASP.NET Core, o aplicativo é hospedado usando ASP.NET ANCM (Core Module) para IIS, Nginx ou Apache. Servidores proxy, balanceadores de carga e outros dispositivos de rede geralmente obscurecem informações sobre a solicitação antes que ela chegue ao aplicativo:
- Quando as solicitações HTTPS são intermediadas por proxy sobre HTTP, o esquema original (HTTPS) é perdido e deve ser encaminhado num cabeçalho.
- Como um aplicativo recebe uma solicitação do proxy e não sua verdadeira fonte na Internet ou na rede corporativa, o endereço IP do cliente de origem também deve ser encaminhado em um cabeçalho.
Essas informações podem ser importantes no processamento de solicitações, por exemplo, em redirecionamentos, autenticação, geração de links, avaliação de políticas e geolocalização do cliente.
Os aplicativos destinados a serem executados em um conjunto de servidores web devem ler Host ASP.NET Core em um conjunto de servidores web.
Cabeçalhos de encaminhamento
Por convenção, proxies encaminham informações em cabeçalhos HTTP.
| Cabeçalho | Descrição |
|---|---|
X-Forwarded-For (XFF) |
Contém informações sobre o cliente que iniciou a solicitação e os proxies subsequentes em uma cadeia de proxies. Este parâmetro pode conter endereços IP e, opcionalmente, números de porta. Em uma cadeia de servidores proxy, o primeiro parâmetro indica o cliente onde a solicitação foi feita pela primeira vez. Seguem-se os identificadores de proxy posteriores. O último proxy na cadeia não está na lista de parâmetros. O endereço IP do último proxy e, opcionalmente, um número de porta, estão disponíveis como o endereço IP remoto na camada de transporte. |
X-Forwarded-Proto (XFP) |
O valor do esquema de origem, HTTP ou HTTPS. O valor também pode ser uma lista de esquemas se a solicitação tiver percorrido vários proxies. |
X-Forwarded-Host (XFH) |
O valor original do campo de cabeçalho do Host. Normalmente, os proxies não modificam o cabeçalho do host. Consulte o Comunicado de Segurança da Microsoft CVE-2018-0787 para obter informações sobre uma vulnerabilidade de elevação de privilégios que afeta sistemas em que o proxy não valida ou restringe cabeçalhos de host a valores válidos. |
X-Forwarded-Prefix |
O caminho base original solicitado pelo cliente. Esse cabeçalho pode ser útil para aplicativos gerarem corretamente URLs, redirecionamentos ou links de volta para o cliente. |
O Middleware de Encaminhamento de Cabeçalhos, ForwardedHeadersMiddleware, lê esses cabeçalhos e preenche os campos associados em HttpContext.
As atualizações de middleware:
-
HttpContext.Connection.RemoteIpAddress: Defina usando o valor de cabeçalhoX-Forwarded-For. Configurações adicionais influenciam como o middleware configuraRemoteIpAddress. Para obter detalhes, consulte as opções de middleware de cabeçalhos encaminhados. Os valores consumidos são removidos deX-Forwarded-For, e o valor antigo deHttpContext.Connection.RemoteIpAddressé preservado emX-Original-For. Nota: Este processo pode ser repetido várias vezes se houver vários valores noX-Forwarded-For/Proto/Host/Prefix, resultando em vários valores movidos paraX-Original-*, incluindo o originalRemoteIpAddress/Host/Scheme/PathBase. -
HttpContext.Request.Scheme: Defina usando o valor de cabeçalhoX-Forwarded-Proto. O valor consumido é removido deX-Forwarded-Proto, e o valor antigo deHttpContext.Request.Schemeé persistido emX-Original-Proto. -
HttpContext.Request.Host: Defina usando o valor de cabeçalhoX-Forwarded-Host. O valor consumido é removido deX-Forwarded-Host, e o valor antigo deHttpContext.Request.Hosté persistido emX-Original-Host. -
HttpContext.Request.PathBase: Defina usando o valor de cabeçalhoX-Forwarded-Prefix. O valor consumido é removido deX-Forwarded-Prefix, e o valor antigo deHttpContext.Request.PathBaseé persistido emX-Original-Prefix.
Para obter mais informações sobre o precedente, consulte este problema do GitHub.
O middleware de cabeçalhos encaminhados pode ter as configurações padrão ajustadas. Para as configurações padrão:
- Há apenas um proxy entre o aplicativo e a origem das solicitações.
- Somente endereços de loopback são configurados para proxies conhecidos e redes conhecidas.
- Os cabeçalhos encaminhados são nomeados
X-Forwarded-For,X-Forwarded-ProtoX-Forwarded-HosteX-Forwarded-Prefix. - O
ForwardedHeadersvalor éForwardedHeaders.None, os encaminhadores desejados devem ser definidos aqui para habilitar o middleware.
Nem todos os dispositivos de rede adicionam os X-Forwarded-For cabeçalhos e X-Forwarded-Proto sem configuração adicional. Consulte as orientações do fabricante do seu aparelho se as solicitações por proxy não contiverem esses cabeçalhos quando chegarem ao aplicativo. Se o aparelho usar nomes de cabeçalho diferentes de X-Forwarded-For e X-Forwarded-Proto, defina as opções ForwardedForHeaderName e ForwardedProtoHeaderName para corresponder aos nomes de cabeçalho usados pelo aparelho. Para obter mais informações, consulte Opções de middleware de cabeçalhos encaminhados e Configuração para um proxy que usa nomes de cabeçalho diferentes.
IIS/IIS Express e ASP.NET Módulo Principal
O middleware de cabeçalhos encaminhados é ativado por padrão pelo middleware de integração do IIS quando o aplicativo é executado fora do processo em segundo plano com o IIS e o ASP.NET Core Module (ANCM) para IIS. O middleware de cabeçalhos encaminhados é ativado para ser executado primeiro no pipeline de middleware com uma configuração restrita específica para o ASP.NET Core Module. A configuração restrita deve-se a preocupações de confiança com cabeçalhos encaminhados, por exemplo, falsificação de IP. O middleware é configurado para encaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto e é restrito a um único proxy localhost. Se for necessária uma configuração adicional, consulte as Opções de Middleware de Cabeçalhos Encaminhados.
Outros cenários de servidor proxy e balanceador de carga
Além de usar a Integração do IIS ao hospedar fora do processo, o middleware de cabeçalhos encaminhados não está habilitado por padrão. O Middleware de Cabeçalhos Encaminhados deve estar ativado para que uma aplicação processe cabeçalhos encaminhados com UseForwardedHeaders. Depois de habilitar o middleware, se nenhum ForwardedHeadersOptions for especificado para o middleware, o padrão é ForwardedHeadersOptions.ForwardedHeaders, que é ForwardedHeaders.None.
Configure o middleware com ForwardedHeadersOptions para encaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto.
Ordem do Middleware de Cabeçalhos Reencaminhados
O middleware de Cabeçalhos Encaminhados deve ser executado antes de outro middleware. Esta ordenação garante que o middleware que depende das informações dos cabeçalhos encaminhados possa usar os valores desses cabeçalhos para processamento. O middleware de cabeçalhos encaminhados pode ser executado após diagnósticos e tratamento de erros, mas deve ser executado antes de chamar UseHsts:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseForwardedHeaders();
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Como alternativa, ligue antes do UseForwardedHeaders diagnóstico:
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();
Observação
Se nenhum ForwardedHeadersOptions for especificado ou aplicado diretamente ao método de extensão com UseForwardedHeaders, os cabeçalhos padrão a serem encaminhados serão ForwardedHeaders.None. A propriedade ForwardedHeaders deve ser configurada com os cabeçalhos a encaminhar.
Configuração do Nginx
Para reencaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto, consulte Host ASP.NET Core no Linux com Nginx. Para obter mais informações, consulte NGINX: Usando o cabeçalho Encaminhado.
Configuração do Apache
X-Forwarded-For é adicionado automaticamente. Para obter mais informações, consulte Apache Module mod_proxy: Reverse Proxy Request Headers.
Opções de middleware de cabeçalhos encaminhados
ForwardedHeadersOptions controlar o comportamento do Forwarded Headers Middleware. O exemplo a seguir altera os valores padrão:
- Limita o número de entradas nos cabeçalhos encaminhados a
2. - Adiciona um endereço proxy conhecido de
127.0.10.1. - Altera o nome do cabeçalho encaminhado do padrão
X-Forwarded-ForparaX-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();
| Opção | Descrição |
|---|---|
| AllowedHosts | Restringe os hosts pelo cabeçalho X-Forwarded-Host para os valores fornecidos.
IList<string>vazio . |
| ForwardedForHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XForwardedForHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o X-Forwarded-For cabeçalho, mas usa algum outro cabeçalho para encaminhar as informações.A predefinição é X-Forwarded-For. |
| ForwardedHeaders | Identifica quais encaminhadores devem ser processados. Consulte o Enum ForwardedHeaders para obter a lista de campos que se aplicam. Os valores típicos atribuídos a esta propriedade são ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.O valor padrão é ForwardedHeaders.None. |
| ForwardedHostHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XForwardedHostHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o X-Forwarded-Host cabeçalho, mas usa algum outro cabeçalho para encaminhar as informações.A predefinição é X-Forwarded-Host. |
| ForwardedProtoHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XForwardedProtoHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o X-Forwarded-Proto cabeçalho, mas usa algum outro cabeçalho para encaminhar as informações.A predefinição é X-Forwarded-Proto. |
| ForwardLimit | Limita o número de entradas nos cabeçalhos que são processados. Defina como null para desativar o limite, mas isso só deve ser feito se KnownProxies ou KnownNetworks estiver configurado. Definir um valor diferente de null serve como precaução (mas não uma garantia) para proteger contra proxies mal configurados e solicitações maliciosas que chegam por canais secundários na rede.O middleware Cabeçalhos Encaminhados processa os cabeçalhos na ordem inversa, da direita para a esquerda. Se o valor padrão ( 1) for usado, apenas o último valor dos cabeçalhos é processado, a menos que o valor de ForwardLimit seja aumentado.A predefinição é 1. |
| KnownNetworks | Intervalos de endereços de redes conhecidas a partir das quais aceitar cabeçalhos encaminhados. Forneça intervalos de IP usando a notação CIDR (Roteamento entre domínios sem classe). Se o servidor estiver usando soquetes de modo duplo, os endereços IPv4 serão fornecidos em um formato IPv6 (por exemplo, 10.0.0.1 em IPv4 representado em IPv6 como ::ffff:10.0.0.1). Consulte IPAddress.MapToIPv6. Determine se esse formato é necessário examinando o HttpContext.Connection.RemoteIpAddress.O padrão é um IList<IPNetwork> contendo uma única entrada para new IPNetwork(IPAddress.Loopback, 8). |
| KnownProxies | Endereços de proxies conhecidos dos quais aceitar cabeçalhos encaminhados. Use KnownProxies para especificar correspondências exatas de endereço IP.Se o servidor estiver usando soquetes de modo duplo, os endereços IPv4 serão fornecidos em um formato IPv6 (por exemplo, 10.0.0.1 em IPv4 representado em IPv6 como ::ffff:10.0.0.1). Consulte IPAddress.MapToIPv6. Determine se esse formato é necessário examinando o HttpContext.Connection.RemoteIpAddress.O padrão é um IList<IPAddress> contendo uma única entrada para IPAddress.IPv6Loopback. |
| OriginalForHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XOriginalForHeaderName. A predefinição é X-Original-For. |
| OriginalHostHeaderName | Use o cabeçalho especificado por essa propriedade em vez do especificado por ForwardedHeadersDefaults.XOriginalHostHeaderName. A predefinição é X-Original-Host. |
| OriginalProtoHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XOriginalProtoHeaderName. A predefinição é X-Original-Proto. |
| RequireHeaderSymmetry | Exija que o número de valores de cabeçalho esteja sincronizado entre os ForwardedHeadersOptions.ForwardedHeaders que estão sendo processados. O padrão no ASP.NET Core 1.x é true. O padrão no ASP.NET Core 2.0 ou posterior é false. |
Cenários e casos de utilização
Quando não é possível adicionar cabeçalhos encaminhados e todas as solicitações são seguras
Em alguns casos, pode não ser possível adicionar cabeçalhos encaminhados nas solicitações encaminhadas via proxy para a aplicação. Se o proxy estiver impondo que todas as solicitações externas públicas sejam HTTPS, o esquema poderá ser definido manualmente antes de usar qualquer tipo de middleware:
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();
Esse código pode ser desabilitado com uma variável de ambiente ou outra definição de configuração em um ambiente de desenvolvimento ou preparação:
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();
Trabalhar com base de caminho e proxies que alteram o caminho da solicitação
Alguns proxies passam o caminho intacto, mas com um caminho base do aplicativo que deve ser removido para que o roteamento funcione corretamente. O middleware UsePathBaseExtensions.UsePathBase divide o caminho em HttpRequest.Path e o caminho base do aplicativo em HttpRequest.PathBase.
Se /foo for o caminho base do aplicativo para um caminho de proxy passado como /foo/api/1, o middleware define Request.PathBase como /foo e Request.Path para /api/1 com o seguinte comando:
app.UsePathBase("/foo");
// ...
app.UseRouting();
Observação
Ao usar WebApplication (consulte Migrar do ASP.NET Core no .NET 5 para o .NET 6), app.UseRouting deve ser chamado depois de UsePathBase para que o middleware de roteamento possa observar o caminho modificado antes de corresponder rotas. Caso contrário, as rotas são correspondidas antes que o caminho seja reescrito por UsePathBase, conforme descrito nos artigos Middleware Ordering e Routing.
O caminho original e a base do caminho são reaplicados quando o middleware é chamado novamente no sentido inverso. Para obter mais informações sobre o processamento de pedidos de middleware, consulte ASP.NET Core Middleware.
Se o proxy cortar o caminho (por exemplo, encaminhando /foo/api/1 para /api/1), corrija redirecionamentos e links definindo a propriedade PathBase da solicitação:
app.Use((context, next) =>
{
context.Request.PathBase = new PathString("/foo");
return next(context);
});
Se o proxy estiver adicionando dados de caminho, descarte parte do caminho para corrigir redirecionamentos e links usando StartsWithSegments e atribuindo à Path propriedade:
app.Use((context, next) =>
{
if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
{
context.Request.Path = remainder;
}
return next(context);
});
Configuração para um proxy que usa nomes de cabeçalho diferentes
Se o proxy não usar cabeçalhos nomeados X-Forwarded-For e X-Forwarded-Proto para encaminhar o endereço/porta do proxy e as informações do esquema de origem, defina as opções ForwardedForHeaderName e ForwardedProtoHeaderName para corresponder aos nomes de cabeçalho usados pelo proxy:
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();
Encaminhar o esquema para proxies reversos Linux e não-IIS
Aplicações que chamam UseHttpsRedirection e UseHsts colocam o site num loop infinito se implantadas em um Serviço de Aplicação Linux do Azure, máquina virtual (VM) do Azure Linux ou atrás de qualquer outro proxy reverso além do IIS. O TLS é encerrado pelo proxy reverso e Kestrel não está ciente do esquema de solicitação correto. OAuth e OIDC também falham nessa configuração porque geram redirecionamentos incorretos. UseIISIntegration adiciona e configura o Middleware de Cabeçalhos Encaminhados quando executado atrás do IIS, mas não existe uma configuração automática equivalente para Linux (integração com Apache ou Nginx).
Para encaminhar o esquema do proxy em cenários que não sejam do IIS, habilite o middleware de cabeçalhos encaminhados definindo ASPNETCORE_FORWARDEDHEADERS_ENABLED como true. Aviso: esse sinalizador usa configurações projetadas para ambientes de nuvem e não habilita recursos como o KnownProxies option para restringir quais encaminhadores de IPs são aceitos.
Encaminhamento de certificados
Azure
Para configurar o Serviço de Aplicativo do Azure para encaminhamento de certificados, consulte Configurar autenticação mútua TLS para o Serviço de Aplicativo do Azure. As diretrizes a seguir referem-se à configuração do aplicativo ASP.NET Core.
- Configure o Middleware de Encaminhamento de Certificados para especificar o nome do cabeçalho que o Azure usa. Adicione o seguinte código para configurar o cabeçalho a partir do qual o middleware cria um certificado.
- Ligue UseCertificateForwarding antes da chamada para 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();
Outros proxies da Internet
Se for usado um proxy que não seja o IIS ou o ARR (Roteamento de Solicitação de Aplicativo) do Serviço de Aplicativo do Azure, configure o proxy para encaminhar o certificado recebido em um cabeçalho HTTP.
- Configure o Middleware de Encaminhamento de Certificados para especificar o nome do cabeçalho. Adicione o seguinte código para configurar o cabeçalho a partir do qual o middleware cria um certificado.
- Ligue UseCertificateForwarding antes da chamada para 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();
Se o proxy não estiver codificando o certificado em base64, como é o caso do Nginx, defina a HeaderConverter opção. Considere o seguinte exemplo:
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();
Solucionar problemas
Quando os cabeçalhos não forem encaminhados conforme o esperado, habilite debug o registo a nível e o registo de solicitações HTTP.
UseHttpLogging deve ser chamado após UseForwardedHeaders:
using Microsoft.AspNetCore.HttpLogging;
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddHttpLogging(options =>
{
options.LoggingFields = HttpLoggingFields.RequestPropertiesAndHeaders;
});
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
var app = builder.Build();
app.UseForwardedHeaders();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
// Connection: RemoteIp
app.Logger.LogInformation("Request RemoteIp: {RemoteIpAddress}",
context.Connection.RemoteIpAddress);
await next(context);
});
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Se houver vários valores em um determinado cabeçalho, o Middleware de Cabeçalhos Encaminhados processará os cabeçalhos na ordem inversa da direita para a esquerda. O padrão ForwardLimit é 1 (um), portanto, apenas o valor mais à direita dos cabeçalhos é processado, a menos que o valor de ForwardLimit seja aumentado.
O IP remoto original da solicitação deve corresponder a uma entrada nas listas KnownProxies ou KnownNetworks antes que os cabeçalhos reencaminhados sejam processados. Isso limita a falsificação de cabeçalho ao não aceitar encaminhadores de proxies não confiáveis. Quando um proxy desconhecido é detetado, o registro em log indica o endereço do proxy:
September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321
No exemplo anterior, 10.0.0.100 é um servidor proxy. Se o servidor for um proxy confiável, adicione o endereço IP do servidor ao KnownProxies, ou adicione uma rede confiável ao KnownNetworks. Para obter mais informações, consulte a seção Opções de middleware de cabeçalhos encaminhados .
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();
Para exibir os logs, adicione "Microsoft.AspNetCore.HttpLogging": "Information" ao appsettings.Development.json arquivo:
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.HttpLogging": "Information"
}
}
}
Importante
Permita apenas que proxies e redes confiáveis encaminhem cabeçalhos. Caso contrário, ataques de falsificação de IP são possíveis.
Recursos adicionais
Na configuração recomendada para o ASP.NET Core, o aplicativo é hospedado usando o IIS/ASP.NET Core Module, Nginx ou Apache. Servidores proxy, balanceadores de carga e outros dispositivos de rede geralmente obscurecem informações sobre a solicitação antes que ela chegue ao aplicativo:
- Quando as solicitações HTTPS são intermediadas por proxy sobre HTTP, o esquema original (HTTPS) é perdido e deve ser encaminhado num cabeçalho.
- Como um aplicativo recebe uma solicitação do proxy e não sua verdadeira fonte na Internet ou na rede corporativa, o endereço IP do cliente de origem também deve ser encaminhado em um cabeçalho.
Essas informações podem ser importantes no processamento de solicitações, por exemplo, em redirecionamentos, autenticação, geração de links, avaliação de políticas e geolocalização do cliente.
Cabeçalhos de encaminhamento
Por convenção, proxies encaminham informações em cabeçalhos HTTP.
| Cabeçalho | Descrição |
|---|---|
| X-Forwarded-For | Contém informações sobre o cliente que iniciou a solicitação e os proxies subsequentes em uma cadeia de proxies. Este parâmetro pode conter endereços IP (e, opcionalmente, números de porta). Em uma cadeia de servidores proxy, o primeiro parâmetro indica o cliente onde a solicitação foi feita pela primeira vez. Seguem-se os identificadores de proxy posteriores. O último proxy na cadeia não está na lista de parâmetros. O endereço IP do último proxy e, opcionalmente, um número de porta, estão disponíveis como o endereço IP remoto na camada de transporte. |
| X-Forwarded-Proto | O valor do esquema de origem (HTTP/HTTPS). O valor também pode ser uma lista de esquemas se a solicitação tiver percorrido vários proxies. |
| X-Forwarded-Host | O valor original do campo de cabeçalho do Host. Normalmente, os proxies não modificam o cabeçalho do host. Consulte o Comunicado de Segurança da Microsoft CVE-2018-0787 para obter informações sobre uma vulnerabilidade de elevação de privilégios que afeta sistemas em que o proxy não valida ou restringe cabeçalhos de host a valores válidos. |
O middleware de cabeçalhos encaminhados (ForwardedHeadersMiddleware), lê esses cabeçalhos e preenche os campos associados em HttpContext.
As atualizações de middleware:
-
HttpContext.Connection.RemoteIpAddress: Definido pelo valor do
X-Forwarded-Forcabeçalho. Configurações adicionais influenciam como o middleware configuraRemoteIpAddress. Para obter detalhes, consulte as opções de middleware de cabeçalhos encaminhados. Os valores consumidos são removidos doX-Forwarded-For, e os valores antigos são mantidos emX-Original-For. O mesmo padrão é aplicado aos outros cabeçalhosHosteProto. -
HttpContext.Request.Scheme: Definido usando o valor do cabeçalho
X-Forwarded-Proto. -
HttpContext.Request.Host: Utilize o valor do cabeçalho
X-Forwarded-Hostpara definir.
Para obter mais informações sobre o precedente, consulte este problema do GitHub.
O middleware de cabeçalhos encaminhados pode ter as configurações padrão ajustadas. Para as configurações padrão:
- Há apenas um proxy entre o aplicativo e a origem das solicitações.
- Somente endereços de loopback são configurados para proxies conhecidos e redes conhecidas.
- Os cabeçalhos encaminhados são nomeados
X-Forwarded-ForeX-Forwarded-Proto. - O
ForwardedHeadersvalor éForwardedHeaders.None, os encaminhadores desejados devem ser definidos aqui para habilitar o middleware.
Nem todos os dispositivos de rede adicionam os X-Forwarded-For cabeçalhos e X-Forwarded-Proto sem configuração adicional. Consulte as orientações do fabricante do seu aparelho se as solicitações por proxy não contiverem esses cabeçalhos quando chegarem ao aplicativo. Se o aparelho usar nomes de cabeçalho diferentes de X-Forwarded-For e X-Forwarded-Proto, defina as opções ForwardedForHeaderName e ForwardedProtoHeaderName para corresponder aos nomes de cabeçalho usados pelo aparelho. Para obter mais informações, consulte Opções de middleware de cabeçalhos encaminhados e Configuração para um proxy que usa nomes de cabeçalho diferentes.
IIS/IIS Express e ASP.NET Módulo Principal
O middleware de cabeçalhos encaminhados é habilitado por padrão pelo middleware de integração do IIS quando o aplicativo é hospedado fora do processo atrás do IIS e do módulo principal ASP.NET. O middleware de cabeçalhos reencaminhados é ativado para executar primeiro no pipeline de middleware com uma configuração restrita específica para o módulo ASP.NET Core devido a preocupações de confiança com cabeçalhos reencaminhados (por exemplo, falsificação de IP). O middleware é configurado para encaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto e é restrito a um único proxy localhost. Se for necessária uma configuração adicional, consulte as Opções de Middleware de Cabeçalhos Encaminhados.
Outros cenários de servidor proxy e balanceador de carga
Além de usar a Integração do IIS ao hospedar fora do processo, o middleware de cabeçalhos encaminhados não está habilitado por padrão. O Middleware de Cabeçalhos Encaminhados deve estar ativado para que uma aplicação processe cabeçalhos encaminhados com UseForwardedHeaders. Depois de habilitar o middleware, se nenhum ForwardedHeadersOptions for especificado para o middleware, o padrão é ForwardedHeadersOptions.ForwardedHeaders, que é ForwardedHeaders.None.
Configure o middleware com ForwardedHeadersOptions para encaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto em Startup.ConfigureServices.
Ordem do Middleware de Cabeçalhos Reencaminhados
O Middleware de Cabeçalhos Encaminhados deve ser executado antes de outros middleware. Esta ordenação garante que o middleware que depende das informações dos cabeçalhos encaminhados possa usar os valores desses cabeçalhos para processamento. O middleware de cabeçalhos encaminhados pode ser executado após diagnósticos e tratamento de erros, mas deve ser executado antes de chamar UseHsts:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseForwardedHeaders();
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Como alternativa, ligue antes do UseForwardedHeaders diagnóstico:
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?}");
});
}
Observação
Se nenhum ForwardedHeadersOptions for especificado no Startup.ConfigureServices ou diretamente para o método de extensão com UseForwardedHeaders, os cabeçalhos padrão a serem encaminhados serão ForwardedHeaders.None. A propriedade ForwardedHeaders deve ser configurada com os cabeçalhos a encaminhar.
Configuração do Nginx
Para reencaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto, consulte Host ASP.NET Core no Linux com Nginx. Para obter mais informações, consulte NGINX: Usando o cabeçalho Encaminhado.
Configuração do Apache
X-Forwarded-For é adicionado automaticamente (consulte Apache Module mod_proxy: Reverse Proxy Request Headers).
Opções de middleware de cabeçalhos encaminhados
ForwardedHeadersOptions controlar o comportamento do middleware dos cabeçalhos encaminhados. O exemplo a seguir altera os valores padrão:
- Limite o número de entradas nos cabeçalhos encaminhados a
2. - Adicione um endereço proxy conhecido de
127.0.10.1. - Altere o nome do cabeçalho encaminhado do padrão
X-Forwarded-ForparaX-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";
});
| Opção | Descrição |
|---|---|
| AllowedHosts | Restringe os hosts pelo cabeçalho X-Forwarded-Host para os valores fornecidos.
IList<string>vazio . |
| ForwardedHeaders | Identifica quais encaminhadores devem ser processados. Consulte o Enum ForwardedHeaders para obter a lista de campos que se aplicam. Os valores típicos atribuídos a esta propriedade são ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.O valor padrão é ForwardedHeaders.None. |
| ForwardedForHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XForwardedForHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o X-Forwarded-For cabeçalho, mas usa algum outro cabeçalho para encaminhar as informações.A predefinição é X-Forwarded-For. |
| ForwardedHostHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XForwardedHostHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o X-Forwarded-Host cabeçalho, mas usa algum outro cabeçalho para encaminhar as informações.A predefinição é X-Forwarded-Host. |
| ForwardedProtoHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XForwardedProtoHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o X-Forwarded-Proto cabeçalho, mas usa algum outro cabeçalho para encaminhar as informações.A predefinição é X-Forwarded-Proto. |
| ForwardedPrefixHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XForwardedPrefixHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o X-Forwarded-Prefix cabeçalho, mas usa algum outro cabeçalho para encaminhar as informações.A predefinição é X-Forwarded-Prefix. |
| ForwardLimit | Limita o número de entradas nos cabeçalhos que são processados. Defina como null para desativar o limite, mas isso só deve ser feito se KnownProxies ou KnownNetworks estiver configurado. Definir um valor diferente de null serve como precaução (mas não uma garantia) para proteger contra proxies mal configurados e solicitações maliciosas que chegam por canais secundários na rede.O middleware Cabeçalhos Encaminhados processa os cabeçalhos na ordem inversa, da direita para a esquerda. Se o valor padrão ( 1) for usado, apenas o último valor dos cabeçalhos é processado, a menos que o valor de ForwardLimit seja aumentado.A predefinição é 1. |
| KnownNetworks | Intervalos de endereços de redes conhecidas a partir das quais aceitar cabeçalhos encaminhados. Forneça intervalos de IP usando a notação CIDR (Roteamento entre domínios sem classe). Se o servidor estiver usando soquetes de modo duplo, os endereços IPv4 serão fornecidos em um formato IPv6 (por exemplo, 10.0.0.1 em IPv4 representado em IPv6 como ::ffff:10.0.0.1). Consulte IPAddress.MapToIPv6. Determine se esse formato é necessário examinando o HttpContext.Connection.RemoteIpAddress.O padrão é um IList<IPNetwork> contendo uma única entrada para new IPNetwork(IPAddress.Loopback, 8). |
| KnownProxies | Endereços de proxies conhecidos dos quais aceitar cabeçalhos encaminhados. Use KnownProxies para especificar correspondências exatas de endereço IP.Se o servidor estiver usando soquetes de modo duplo, os endereços IPv4 serão fornecidos em um formato IPv6 (por exemplo, 10.0.0.1 em IPv4 representado em IPv6 como ::ffff:10.0.0.1). Consulte IPAddress.MapToIPv6. Determine se esse formato é necessário examinando o HttpContext.Connection.RemoteIpAddress.O padrão é um IList<IPAddress> contendo uma única entrada para IPAddress.IPv6Loopback. |
| OriginalForHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XOriginalForHeaderName. A predefinição é X-Original-For. |
| OriginalHostHeaderName | Use o cabeçalho especificado por essa propriedade em vez do especificado por ForwardedHeadersDefaults.XOriginalHostHeaderName. A predefinição é X-Original-Host. |
| OriginalProtoHeaderName | Use o cabeçalho especificado por esta propriedade em vez do especificado por ForwardedHeadersDefaults.XOriginalProtoHeaderName. A predefinição é X-Original-Proto. |
| OriginalPrefixHeaderName | Use o cabeçalho especificado por essa propriedade em vez do especificado por ForwardedHeadersDefaults.XOriginalPrefixHeaderName. A predefinição é X-Original-Prefix. |
| RequireHeaderSymmetry | Exija que o número de valores de cabeçalho esteja sincronizado entre os ForwardedHeadersOptions.ForwardedHeaders que estão sendo processados. O padrão no ASP.NET Core 1.x é true. O padrão no ASP.NET Core 2.0 ou posterior é false. |
Cenários e casos de utilização
Quando não é possível adicionar cabeçalhos encaminhados e todas as solicitações são seguras
Em alguns casos, pode não ser possível adicionar cabeçalhos encaminhados nas solicitações encaminhadas via proxy para a aplicação. Se o proxy estiver impondo que todas as solicitações externas públicas sejam HTTPS, o esquema poderá ser definido Startup.Configure manualmente antes de usar qualquer tipo de middleware:
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
Esse código pode ser desabilitado com uma variável de ambiente ou outra definição de configuração em um ambiente de desenvolvimento ou preparação.
Lidar com a base de caminho e proxies que alteram o caminho da solicitação
Alguns proxies passam o caminho intacto, mas com um caminho base do aplicativo que deve ser removido para que o roteamento funcione corretamente. O middleware UsePathBaseExtensions.UsePathBase divide o caminho em HttpRequest.Path e o caminho base do aplicativo em HttpRequest.PathBase.
Se /foo for o caminho base do aplicativo para um caminho de proxy passado como /foo/api/1, o middleware define Request.PathBase como /foo e Request.Path para /api/1 com o seguinte comando:
app.UsePathBase("/foo");
O caminho original e a base do caminho são reaplicados quando o middleware é chamado novamente no sentido inverso. Para obter mais informações sobre o processamento de pedidos de middleware, consulte ASP.NET Core Middleware.
Se o proxy cortar o caminho (por exemplo, encaminhando /foo/api/1 para /api/1), corrija redirecionamentos e links definindo a propriedade PathBase da solicitação:
app.Use((context, next) =>
{
context.Request.PathBase = new PathString("/foo");
return next();
});
Se o proxy estiver adicionando dados de caminho, descarte parte do caminho para corrigir redirecionamentos e links usando StartsWithSegments e atribuindo à Path propriedade:
app.Use((context, next) =>
{
if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
{
context.Request.Path = remainder;
}
return next();
});
Configuração para um proxy que usa nomes de cabeçalho diferentes
Se o proxy não usar cabeçalhos nomeados X-Forwarded-For e X-Forwarded-Proto para encaminhar o endereço/porta do proxy e as informações do esquema de origem, defina as opções ForwardedForHeaderName e ForwardedProtoHeaderName para corresponder aos nomes de cabeçalho usados pelo proxy:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedForHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-For_Header";
options.ForwardedProtoHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-Proto_Header";
});
Encaminhar o esquema para proxies reversos Linux e não-IIS
Aplicações que chamam UseHttpsRedirection e UseHsts colocam o site num loop infinito se implantadas em um Serviço de Aplicação Linux do Azure, máquina virtual (VM) do Azure Linux ou atrás de qualquer outro proxy reverso além do IIS. O TLS é encerrado pelo proxy reverso e Kestrel não está ciente do esquema de solicitação correto. OAuth e OIDC também falham nessa configuração porque geram redirecionamentos incorretos. UseIISIntegration adiciona e configura o Middleware de Cabeçalhos Encaminhados quando executado atrás do IIS, mas não existe uma configuração automática equivalente para Linux (integração com Apache ou Nginx).
Para encaminhar o esquema do proxy em cenários que não sejam do IIS, adicione e configure o middleware de cabeçalhos encaminhados. No Startup.ConfigureServices, use o seguinte código:
// 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();
});
}
Encaminhamento de certificados
Azure
Para configurar o Serviço de Aplicativo do Azure para encaminhamento de certificados, consulte Configurar autenticação mútua TLS para o Serviço de Aplicativo do Azure. As diretrizes a seguir referem-se à configuração do aplicativo ASP.NET Core.
No Startup.Configure, adicione o seguinte código antes da chamada para app.UseAuthentication();:
app.UseCertificateForwarding();
Configure o Middleware de Encaminhamento de Certificados para especificar o nome do cabeçalho que o Azure usa. No Startup.ConfigureServices, adicione o seguinte código para configurar o cabeçalho a partir do qual o middleware cria um certificado:
services.AddCertificateForwarding(options =>
options.CertificateHeader = "X-ARR-ClientCert");
Outros proxies da Internet
Se for usado um proxy que não seja o IIS ou o ARR (Roteamento de Solicitação de Aplicativo) do Serviço de Aplicativo do Azure, configure o proxy para encaminhar o certificado recebido em um cabeçalho HTTP. No Startup.Configure, adicione o seguinte código antes da chamada para app.UseAuthentication();:
app.UseCertificateForwarding();
Configure o middleware de encaminhamento de certificado para especificar o nome do cabeçalho. No Startup.ConfigureServices, adicione o seguinte código para configurar o cabeçalho a partir do qual o middleware cria um certificado:
services.AddCertificateForwarding(options =>
options.CertificateHeader = "YOUR_CERTIFICATE_HEADER_NAME");
Se o proxy não estiver codificando o certificado em base64 (como é o caso do Nginx), defina a HeaderConverter opção. Considere o seguinte exemplo em 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;
}
});
Solucionar problemas
Quando os cabeçalhos não forem encaminhados conforme o esperado, habilite o registro. Se os logs não fornecerem informações suficientes para solucionar o problema, enumere os cabeçalhos de solicitação recebidos pelo servidor. Use middleware embutido para gravar cabeçalhos de solicitação em uma resposta de aplicativo ou registrar os cabeçalhos.
Para gravar os cabeçalhos na resposta do aplicativo, coloque o seguinte middleware em linha do terminal imediatamente após a chamada para UseForwardedHeaders :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}");
});
Você pode gravar em logs em vez do corpo da resposta. A gravação em logs permite que o site funcione normalmente durante a depuração.
Para gravar logs em vez de escrever no corpo da resposta:
- Injete
ILogger<Startup>naStartupclasse como descrito em Criar logs na inicialização. - Coloque o seguinte middleware embutido imediatamente após a chamada para UseForwardedHeaders em
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();
});
Quando processados, X-Forwarded-{For|Proto|Host|Prefix} os valores são movidos para X-Original-{For|Proto|Host|Prefix}. Se houver vários valores em um determinado cabeçalho, o Middleware de Cabeçalhos Encaminhados processará os cabeçalhos na ordem inversa da direita para a esquerda. O padrão ForwardLimit é 1 (um), portanto, apenas o valor mais à direita dos cabeçalhos é processado, a menos que o valor de ForwardLimit seja aumentado.
O IP remoto original da solicitação deve corresponder a uma entrada nas listas KnownProxies ou KnownNetworks antes que os cabeçalhos reencaminhados sejam processados. Isso limita a falsificação de cabeçalho ao não aceitar encaminhadores de proxies não confiáveis. Quando um proxy desconhecido é detetado, o registro em log indica o endereço do proxy:
September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321
No exemplo anterior, 10.0.0.100 é um servidor proxy. Se o servidor for um proxy confiável, adicione o endereço IP do servidor a KnownProxies (ou adicione uma rede confiável a KnownNetworks) em Startup.ConfigureServices. Para obter mais informações, consulte a seção Opções de middleware de cabeçalhos encaminhados .
services.Configure<ForwardedHeadersOptions>(options =>
{
options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});
Importante
Permita apenas que proxies e redes confiáveis encaminhem cabeçalhos. Caso contrário, ataques de falsificação de IP são possíveis.