Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. 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 9 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Por Chris Ross
Na configuração recomendada para o ASP.NET Core, o aplicativo é hospedado usando o Módulo do ASP.NET Core para IIS, Nginx ou Apache. Servidores proxy, balanceadores de carga e outros dispositivos de rede geralmente ocultam informações sobre a solicitação antes de ela alcançar o aplicativo:
- Quando solicitações HTTPS são passadas por proxy por HTTP, o esquema original (HTTPS) é perdido e deve ser encaminhado em um cabeçalho.
- Devido a um aplicativo receber uma solicitação do proxy e não de sua origem verdadeira na Internet ou rede corporativa, o endereço IP do cliente originador 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 link, avaliação de política e localização geográfica do cliente.
Os aplicativos destinados a serem executados no farm da Web devem ler Host ASP.NET Core em um farm da Web.
Cabeçalhos encaminhados
Por convenção, os proxies encaminham informações em cabeçalhos HTTP.
parâmetro | 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. Esse parâmetro pode conter endereços IP e, opcionalmente, os números de porta. Em uma cadeia de servidores proxy, o primeiro parâmetro indica o cliente em que a solicitação foi feita pela primeira vez. Depois, vêm os identificadores de proxy subsequentes. 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 da 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 percorreu 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. Veja Microsoft Security Advisory CVE-2018-0787 para obter informações sobre uma vulnerabilidade de elevação de privilégios que afeta os sistemas em que o proxy não valida ou restringe cabeçalhos de Host a valores válidos conhecidos. |
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 cabeçalhos encaminhados ForwardedHeadersMiddleware lê esses cabeçalhos e preenche os campos associados em HttpContext.
As atualizações de middleware:
HttpContext.Connection.RemoteIpAddress
: defina usando o valor do cabeçalhoX-Forwarded-For
. Configurações adicionais influenciam o modo como o middleware defineRemoteIpAddress
. Para obter detalhes, veja 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
é persistido emX-Original-For
. Observação: esse processo poderá ser repetido várias vezes se houver vários valores emX-Forwarded-For/Proto/Host/Prefix
, resultando em vários valores movidos paraX-Original-*
, incluindo oRemoteIpAddress/Host/Scheme/PathBase
original.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
.
Saiba mais neste tópico do GitHub.
As configurações padrão de middleware de cabeçalhos encaminhados podem ser definidas. Para as configurações padrão:
- Há apenas um proxy entre o aplicativo e a origem das solicitações.
- Somente os 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-Proto
,X-Forwarded-Host
eX-Forwarded-Prefix
. - O valor
ForwardedHeaders
éForwardedHeaders.None
, os encaminhadores desejados devem ser definidos aqui para habilitar o middleware.
Nem todos os dispositivos de rede adicionam os cabeçalhos X-Forwarded-For
e X-Forwarded-Proto
sem configuração adicional. Consulte as diretrizes do fabricante do dispositivo se as solicitações de proxies não contiverem esses cabeçalhos quando atingirem o aplicativo. Se o dispositivo usar nomes de cabeçalho diferente de X-Forwarded-For
e X-Forwarded-Proto
, defina as opções ForwardedForHeaderName e ForwardedProtoHeaderName para corresponder aos nomes de cabeçalho usados pelo dispositivo. Para obter mais informações, consulte Forwarded Headers Middleware options (Opções de middleware de cabeçalhos encaminhados) e Configuration for a proxy that uses different header names (Configuração de um proxy que usa diferentes nomes de cabeçalho).
O IIS/IIS Express e o Módulo do ASP.NET Core
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 do ASP.NET Core 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 Módulo do ASP.NET Core. A configuração restrita é devido a preocupações de confiança com cabeçalhos encaminhados, por exemplo, falsificação de IP. O middleware está configurado para encaminhar os cabeçalhos X-Forwarded-For
e X-Forwarded-Proto
e é restrito a um proxy de localhost único. Se configuração adicional for necessária, veja 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 quando hospedar fora do processo, o Middleware de cabeçalhos encaminhados não é habilitado por padrão. O middleware de cabeçalhos encaminhados deve ser habilitado para um aplicativo para processar cabeçalhos encaminhados com UseForwardedHeaders. Após a habilitação do middleware, se nenhum ForwardedHeadersOptions for especificado para o middleware, o ForwardedHeadersOptions.ForwardedHeaders padrão será ForwardedHeaders.None.
Configure o middleware com ForwardedHeadersOptions para encaminhar os cabeçalhos X-Forwarded-For
e X-Forwarded-Proto
.
Ordem de Middleware de Cabeçalhos Encaminhados
Middlewares de Cabeçalhos Encaminhados devem ser executados antes de outros middlewares. Essa ordenação garantirá que o middleware conte com informações de cabeçalhos encaminhadas que podem consumir os valores de cabeçalho para processamento. O middleware de cabeçalhos encaminhados pode ser executado após diagnóstico e tratamento de erros, mas ele 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, chame UseForwardedHeaders
antes do 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 no método de extensão com UseForwardedHeaders, os cabeçalhos padrão para encaminhar serão ForwardedHeaders.None. A propriedade ForwardedHeaders deve ser configurada com os cabeçalhos para encaminhar.
Configuração de Nginx
Para encaminhar os cabeçalhos X-Forwarded-For
e X-Forwarded-Proto
, confira Host ASP.NET Core no Linux com Nginx. Para obter mais informações, veja NGINX: usando o cabeçalho encaminhado.
Configuração do Apache
X-Forwarded-For
é adicionado automaticamente. Para obter mais informações, confira mod_proxy do módulo do Apache: cabeçalhos de solicitação de proxy reverso.
Opções de middleware de cabeçalhos encaminhados
ForwardedHeadersOptions controla o comportamento do middleware de cabeçalhos encaminhados. O seguinte exemplo altera os valores padrão:
- Limita o número de entradas nos cabeçalhos encaminhados a
2
. - Adiciona um endereço de proxy conhecido de
127.0.10.1
. - Altera o nome do cabeçalho encaminhado do padrão
X-Forwarded-For
paraX-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 com o cabeçalho X-Forwarded-Host para os valores fornecidos.
IList<string> vazio. |
ForwardedForHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XForwardedForHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o cabeçalho X-Forwarded-For , mas usa algum outro cabeçalho para encaminhar as informações.O padrão é X-Forwarded-For . |
ForwardedHeaders | Identifica quais encaminhadores devem ser processados. Veja o ForwardedHeaders Enum para a lista de campos aplicáveis. Os valores típicos atribuídos a essa propriedade são ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto .O valor padrão é ForwardedHeaders.None. |
ForwardedHostHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XForwardedHostHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o cabeçalho X-Forwarded-Host , mas usa algum outro cabeçalho para encaminhar as informações.O padrão é X-Forwarded-Host . |
ForwardedProtoHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XForwardedProtoHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o cabeçalho X-Forwarded-Proto , mas usa algum outro cabeçalho para encaminhar as informações.O padrão é X-Forwarded-Proto . |
ForwardLimit | Limita o número de entradas nos cabeçalhos que são processados. Defina para null para desabilitar o limite, mas isso só deve ser feito se KnownProxies ou KnownNetworks estão configurados. A definição de um valor não null é feita por precaução (o que não implica em uma garantia), para proteção contra proxies mal configurados e solicitações mal-intencionadas que chegam de canais secundários na rede.O middleware de cabeçalhos encaminhados processa cabeçalhos na ordem inversa, da direita para esquerda. Se o valor padrão for usado ( 1 ), apenas o valor mais à direita dos cabeçalhos será processado, a menos que o valor de ForwardLimit seja aumentado.O padrão é 1 . |
KnownNetworks | Intervalos de endereços de redes conhecidas dos quais aceitar cabeçalhos encaminhados. Forneça os intervalos de IP usando notação de CIDR (Roteamento entre Domínios sem Classificação). O servidor usa soquetes de modo duplo e os endereços IPv4 são fornecidos em um formato IPv6 (por exemplo, 10.0.0.1 no formato IPv4 representado no formato IPv6 como ::ffff:10.0.0.1 ). Confira IPAddress.MapToIPv6. Para determinar se este formato é obrigatório, veja HttpContext.Connection.RemoteIpAddress.O padrão é uma IList <IPNetwork> que contém uma única entrada para new IPNetwork(IPAddress.Loopback, 8) . |
KnownProxies | Endereços de proxies conhecidos dos quais aceitar cabeçalhos encaminhados. Use KnownProxies especificar correspondências exatas de endereço IP.O servidor usa soquetes de modo duplo e os endereços IPv4 são fornecidos em um formato IPv6 (por exemplo, 10.0.0.1 no formato IPv4 representado no formato IPv6 como ::ffff:10.0.0.1 ). Confira IPAddress.MapToIPv6. Para determinar se este formato é obrigatório, veja HttpContext.Connection.RemoteIpAddress.O padrão é uma IList <IPAddress> que contém uma única entrada para IPAddress.IPv6Loopback . |
OriginalForHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XOriginalForHeaderName. O padrão é X-Original-For . |
OriginalHostHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XOriginalHostHeaderName. O padrão é X-Original-Host . |
OriginalProtoHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XOriginalProtoHeaderName. O padrão é X-Original-Proto . |
RequireHeaderSymmetry | Exigem o número de valores de cabeçalho a serem sincronizados entre os ForwardedHeadersOptions.ForwardedHeaders 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 uso
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 para as solicitações passadas por proxy ao aplicativo. Se o proxy está impondo que todas as solicitações externas públicas sejam HTTPS, o esquema pode 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 preparo ou de desenvolvimento:
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 o caminho base e proxies que alteram o caminho da solicitação
Alguns proxies passam o caminho intacto, mas com um caminho base de aplicativo que deve ser removido para que o roteamento funcione corretamente. O middleware de UsePathBaseExtensions.UsePathBase divide o caminho em HttpRequest.Path e o caminho base do aplicativo em HttpRequest.PathBase.
Se /foo
é o caminho base do aplicativo para um caminho de proxy passado como /foo/api/1
, o middleware define Request.PathBase
para /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 5.0 para o 6.0), app.UseRouting
precisa ser chamado após UsePathBase
para que o middleware de roteamento possa observar o caminho modificado antes de fazer a correspondência entre as rotas. Caso contrário, a correspondência das rotas é feita antes que o caminho seja reescrito por UsePathBase
, conforme descrito nos artigos Ordenação de middleware e Roteamento.
O caminho original e o caminho base são reaplicados quando o middleware é chamado novamente na ordem inversa. Para obter mais informações sobre o processamento de ordem de middleware, veja Middleware do ASP.NET Core.
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 a parte do caminho para corrigir os redirecionamentos e links usando StartsWithSegments e atribuindo à propriedade Path:
app.Use((context, next) =>
{
if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
{
context.Request.Path = remainder;
}
return next(context);
});
Configuração de um proxy que usa diferentes nomes de cabeçalho
Se o proxy não usar cabeçalhos nomeados X-Forwarded-For
e X-Forwarded-Proto
para encaminhar a porta/endereço do proxy e as informações de origem do esquema, 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 não IIS e Linux
Os aplicativos que chamam UseHttpsRedirection e UseHsts colocam um site em um loop infinito se implantado em um Serviço de Aplicativo do Linux do Azure, VM (máquina virtual) do Azure no Linux ou atrás de outro proxy reverso além do IIS. O TLS é encerrado pelo proxy inverso e o Kestrel não é informado do esquema de solicitação correto. OAuth e OIDC também falham nessa configuração, pois geram redirecionamentos incorretos. UseIISIntegration adiciona e configura o Middleware de Cabeçalhos Encaminhados quando executado atrás do IIS, mas não há nenhuma configuração automática correspondente para Linux (integração do Apache ou do Nginx).
Para encaminhar o esquema do proxy em cenários não de 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 permite recursos como KnownProxies option
para restringir quais encaminhadores de IPs são aceitos.
Encaminhamento de certificado
Azure
Para configurar o Serviço de Aplicativo do Azure para encaminhamento de certificado, confira Configurar a autenticação mútua do 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 Certificado para especificar o nome de cabeçalho que o Azure usa. Adicione o código a seguir para configurar o cabeçalho do qual o middleware cria um certificado.
- Chame 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 Web
Se um proxy que não seja IIS ou ARR (Application Request Routing) do Serviço de Aplicativo do Azure for usado, configure o proxy para encaminhar o certificado que ele recebeu em um cabeçalho HTTP.
- Configure o Middleware de Encaminhamento de Certificado para especificar o nome de cabeçalho. Adicione o código a seguir para configurar o cabeçalho do qual o middleware cria um certificado.
- Chame 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 base64, como é o caso do Nginx, defina a opção HeaderConverter
. 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 são encaminhados conforme o esperado, habilite o registro em log no nível de debug
e o registro em log 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();
Quando houver vários valores em um determinado cabeçalho, o middleware de cabeçalhos encaminhados os processará na ordem inversa, da direita para esquerda. O padrão ForwardLimit
é ForwardLimit
(um), portanto, apenas o valor mais à direita dos cabeçalhos será processado, a menos que o valor de 1
seja aumentado.
O IP de remoto original da solicitação precisa corresponder a uma entrada nas listas KnownProxies ou KnownNetworks antes dos cabeçalhos encaminhados serem processados. Isso limita a falsificação de cabeçalho por não aceitar encaminhadores de proxies não confiáveis. Quando um proxy desconhecido é detectado, o registro em log indica o endereço dele:
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
. 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 arquivo appsettings.Development.json
:
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.HttpLogging": "Information"
}
}
}
Importante
Permitir que somente proxies e redes confiáveis encaminhem os cabeçalhos. Caso contrário, podem ocorrer ataques de falsificação de IP.
Recursos adicionais
Na configuração recomendada para o ASP.NET Core, o aplicativo é hospedado usando IIS/Módulo do ASP.NET Core, Nginx ou Apache. Servidores proxy, balanceadores de carga e outros dispositivos de rede geralmente ocultam informações sobre a solicitação antes de ela alcançar o aplicativo:
- Quando solicitações HTTPS são passadas por proxy por HTTP, o esquema original (HTTPS) é perdido e deve ser encaminhado em um cabeçalho.
- Devido a um aplicativo receber uma solicitação do proxy e não de sua origem verdadeira na Internet ou rede corporativa, o endereço IP do cliente originador 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 link, avaliação de política e localização geográfica do cliente.
Cabeçalhos encaminhados
Por convenção, os proxies encaminham informações em cabeçalhos HTTP.
parâmetro | 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. Esse parâmetro pode conter endereços IP (e, opcionalmente, os números de porta). Em uma cadeia de servidores proxy, o primeiro parâmetro indica o cliente em que a solicitação foi feita pela primeira vez. Depois, vêm os identificadores de proxy subsequentes. 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 da 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 percorreu 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. Veja Microsoft Security Advisory CVE-2018-0787 para obter informações sobre uma vulnerabilidade de elevação de privilégios que afeta os sistemas em que o proxy não valida ou restringe cabeçalhos de Host a valores válidos conhecidos. |
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 usando o valor do cabeçalho
X-Forwarded-For
. Configurações adicionais influenciam o modo como o middleware defineRemoteIpAddress
. Para obter detalhes, veja as Opções de middleware de cabeçalhos encaminhados. Os valores consumidos são removidos deX-Forwarded-For
e os valores antigos são persistidos emX-Original-For
. O mesmo padrão é aplicado aos outros cabeçalhosHost
eProto
. - HttpContext.Request.Scheme: definido usando o valor do cabeçalho
X-Forwarded-Proto
. - HttpContext.Request.Host: definido usando o valor do cabeçalho
X-Forwarded-Host
.
Saiba mais neste tópico do GitHub.
As configurações padrão de middleware de cabeçalhos encaminhados podem ser definidas. Para as configurações padrão:
- Há apenas um proxy entre o aplicativo e a origem das solicitações.
- Somente os endereços de loopback são configurados para proxies conhecidos e redes conhecidas.
- Os cabeçalhos encaminhados são nomeados
X-Forwarded-For
eX-Forwarded-Proto
. - O valor
ForwardedHeaders
éForwardedHeaders.None
, os encaminhadores desejados devem ser definidos aqui para habilitar o middleware.
Nem todos os dispositivos de rede adicionam os cabeçalhos X-Forwarded-For
e X-Forwarded-Proto
sem configuração adicional. Consulte as diretrizes do fabricante do dispositivo se as solicitações de proxies não contiverem esses cabeçalhos quando atingirem o aplicativo. Se o dispositivo usar nomes de cabeçalho diferente de X-Forwarded-For
e X-Forwarded-Proto
, defina as opções ForwardedForHeaderName e ForwardedProtoHeaderName para corresponder aos nomes de cabeçalho usados pelo dispositivo. Para obter mais informações, consulte Forwarded Headers Middleware options (Opções de middleware de cabeçalhos encaminhados) e Configuration for a proxy that uses different header names (Configuração de um proxy que usa diferentes nomes de cabeçalho).
O IIS/IIS Express e o Módulo do ASP.NET Core
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 do ASP.NET Core. O middleware de cabeçalhos encaminhados é ativado para ser executado primeiro no pipeline de middleware, com uma configuração restrita específica para o Módulo do ASP.NET Core devido a questões de confiança com cabeçalhos encaminhados (por exemplo, falsificação de IP). O middleware está configurado para encaminhar os cabeçalhos X-Forwarded-For
e X-Forwarded-Proto
e é restrito a um proxy de localhost único. Se configuração adicional for necessária, veja 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 quando hospedar fora do processo, o Middleware de cabeçalhos encaminhados não é habilitado por padrão. O middleware de cabeçalhos encaminhados deve ser habilitado para um aplicativo para processar cabeçalhos encaminhados com UseForwardedHeaders. Após a habilitação do middleware, se nenhum ForwardedHeadersOptions for especificado para o middleware, o ForwardedHeadersOptions.ForwardedHeaders padrão será ForwardedHeaders.None.
Configure o middleware com ForwardedHeadersOptions para encaminhar os cabeçalhos X-Forwarded-For
e X-Forwarded-Proto
em Startup.ConfigureServices
.
Ordem de Middleware de Cabeçalhos Encaminhados
Middlewares de Cabeçalhos Encaminhados devem ser executados antes de outros middlewares. Essa ordenação garantirá que o middleware conte com informações de cabeçalhos encaminhadas que podem consumir os valores de cabeçalho para processamento. O middleware de cabeçalhos encaminhados pode ser executado após diagnóstico e tratamento de erros, mas ele 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, chame UseForwardedHeaders
antes do 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 no método de extensão com UseForwardedHeaders, os cabeçalhos padrão para encaminhar serão ForwardedHeaders.None. A propriedade ForwardedHeaders deve ser configurada com os cabeçalhos para encaminhar.
Configuração de Nginx
Para encaminhar os cabeçalhos X-Forwarded-For
e X-Forwarded-Proto
, confira Host ASP.NET Core no Linux com Nginx. Para obter mais informações, veja NGINX: usando o cabeçalho encaminhado.
Configuração do Apache
X-Forwarded-For
é adicionado automaticamente (veja mod_proxy do módulo do Apache: cabeçalhos de solicitação de proxy reverso).
Opções de middleware de cabeçalhos encaminhados
ForwardedHeadersOptions controla o comportamento do middleware de cabeçalhos encaminhados. O seguinte exemplo altera os valores padrão:
- Limite o número de entradas nos cabeçalhos encaminhados a
2
. - Adicione um endereço de proxy conhecido de
127.0.10.1
. - Altere o nome do cabeçalho encaminhado do padrão
X-Forwarded-For
paraX-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 com o cabeçalho X-Forwarded-Host para os valores fornecidos.
IList<string> vazio. |
ForwardedHeaders | Identifica quais encaminhadores devem ser processados. Veja o ForwardedHeaders Enum para a lista de campos aplicáveis. Os valores típicos atribuídos a essa propriedade são ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto .O valor padrão é ForwardedHeaders.None. |
ForwardedForHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XForwardedForHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o cabeçalho X-Forwarded-For , mas usa algum outro cabeçalho para encaminhar as informações.O padrão é X-Forwarded-For . |
ForwardedHostHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XForwardedHostHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o cabeçalho X-Forwarded-Host , mas usa algum outro cabeçalho para encaminhar as informações.O padrão é X-Forwarded-Host . |
ForwardedProtoHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XForwardedProtoHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o cabeçalho X-Forwarded-Proto , mas usa algum outro cabeçalho para encaminhar as informações.O padrão é X-Forwarded-Proto . |
ForwardedPrefixHeaderName | Use o cabeçalho especificado por essa propriedade em vez do especificado por ForwardedHeadersDefaults.XForwardedPrefixHeaderName. Esta opção é usada quando o proxy/encaminhador não usa o cabeçalho X-Forwarded-Prefix , mas usa algum outro cabeçalho para encaminhar as informações.O padrão é X-Forwarded-Prefix . |
ForwardLimit | Limita o número de entradas nos cabeçalhos que são processados. Defina para null para desabilitar o limite, mas isso só deve ser feito se KnownProxies ou KnownNetworks estão configurados. A definição de um valor não null é feita por precaução (o que não implica em uma garantia), para proteção contra proxies mal configurados e solicitações mal-intencionadas que chegam de canais secundários na rede.O middleware de cabeçalhos encaminhados processa cabeçalhos na ordem inversa, da direita para esquerda. Se o valor padrão for usado ( 1 ), apenas o valor mais à direita dos cabeçalhos será processado, a menos que o valor de ForwardLimit seja aumentado.O padrão é 1 . |
KnownNetworks | Intervalos de endereços de redes conhecidas dos quais aceitar cabeçalhos encaminhados. Forneça os intervalos de IP usando notação de CIDR (Roteamento entre Domínios sem Classificação). O servidor usa soquetes de modo duplo e os endereços IPv4 são fornecidos em um formato IPv6 (por exemplo, 10.0.0.1 no formato IPv4 representado no formato IPv6 como ::ffff:10.0.0.1 ). Confira IPAddress.MapToIPv6. Para determinar se este formato é obrigatório, veja HttpContext.Connection.RemoteIpAddress.O padrão é uma IList <IPNetwork> que contém uma única entrada para new IPNetwork(IPAddress.Loopback, 8) . |
KnownProxies | Endereços de proxies conhecidos dos quais aceitar cabeçalhos encaminhados. Use KnownProxies especificar correspondências exatas de endereço IP.O servidor usa soquetes de modo duplo e os endereços IPv4 são fornecidos em um formato IPv6 (por exemplo, 10.0.0.1 no formato IPv4 representado no formato IPv6 como ::ffff:10.0.0.1 ). Confira IPAddress.MapToIPv6. Para determinar se este formato é obrigatório, veja HttpContext.Connection.RemoteIpAddress.O padrão é uma IList <IPAddress> que contém uma única entrada para IPAddress.IPv6Loopback . |
OriginalForHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XOriginalForHeaderName. O padrão é X-Original-For . |
OriginalHostHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XOriginalHostHeaderName. O padrão é X-Original-Host . |
OriginalProtoHeaderName | Use o cabeçalho especificado por essa propriedade, em vez de um especificado por ForwardedHeadersDefaults.XOriginalProtoHeaderName. O padrão é X-Original-Proto . |
OriginalPrefixHeaderName | Use o cabeçalho especificado por essa propriedade em vez do especificado por ForwardedHeadersDefaults.XOriginalPrefixHeaderName. O padrão é X-Original-Prefix . |
RequireHeaderSymmetry | Exigem o número de valores de cabeçalho a serem sincronizados entre os ForwardedHeadersOptions.ForwardedHeaders 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 uso
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 para as solicitações passadas por proxy ao aplicativo. Se o proxy está impondo que todas as solicitações externas públicas sejam HTTPS, o esquema pode ser definido manualmente em Startup.Configure
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 preparo ou de desenvolvimento.
Lidar com o caminho base e proxies que alteram o caminho da solicitação
Alguns proxies passam o caminho intacto, mas com um caminho base de aplicativo que deve ser removido para que o roteamento funcione corretamente. O middleware de UsePathBaseExtensions.UsePathBase divide o caminho em HttpRequest.Path e o caminho base do aplicativo em HttpRequest.PathBase.
Se /foo
é o caminho base do aplicativo para um caminho de proxy passado como /foo/api/1
, o middleware define Request.PathBase
para /foo
e Request.Path
para /api/1
com o seguinte comando:
app.UsePathBase("/foo");
O caminho original e o caminho base são reaplicados quando o middleware é chamado novamente na ordem inversa. Para obter mais informações sobre o processamento de ordem de middleware, veja Middleware do ASP.NET Core.
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 a parte do caminho para corrigir os redirecionamentos e links usando StartsWithSegments e atribuindo à propriedade Path:
app.Use((context, next) =>
{
if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
{
context.Request.Path = remainder;
}
return next();
});
Configuração de um proxy que usa diferentes nomes de cabeçalho
Se o proxy não usar cabeçalhos nomeados X-Forwarded-For
e X-Forwarded-Proto
para encaminhar a porta/endereço do proxy e as informações de origem do esquema, 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 não IIS e Linux
Os aplicativos que chamam UseHttpsRedirection e UseHsts colocam um site em um loop infinito se implantado em um Serviço de Aplicativo do Linux do Azure, VM (máquina virtual) do Azure no Linux ou atrás de outro proxy reverso além do IIS. O TLS é encerrado pelo proxy inverso e o Kestrel não é informado do esquema de solicitação correto. OAuth e OIDC também falham nessa configuração, pois geram redirecionamentos incorretos. UseIISIntegration adiciona e configura o Middleware de Cabeçalhos Encaminhados quando executado atrás do IIS, mas não há nenhuma configuração automática correspondente para Linux (integração do Apache ou do Nginx).
Para encaminhar o esquema do proxy em cenários não de IIS, adicione e configure o Middleware de Cabeçalhos Encaminhados. No Startup.ConfigureServices
, use o código a seguir:
// 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 certificado
Azure
Para configurar o Serviço de Aplicativo do Azure para encaminhamento de certificado, confira Configurar a autenticação mútua do TLS para o Serviço de Aplicativo do Azure. As diretrizes a seguir referem-se à configuração do aplicativo ASP.NET Core.
Em Startup.Configure
, adicione o código a seguir antes da chamada para app.UseAuthentication();
:
app.UseCertificateForwarding();
Configure o Middleware de Encaminhamento de Certificado para especificar o nome de cabeçalho que o Azure usa. Em Startup.ConfigureServices
, adicione o código a seguir para configurar o cabeçalho do qual o middleware cria um certificado:
services.AddCertificateForwarding(options =>
options.CertificateHeader = "X-ARR-ClientCert");
Outros proxies da Web
Se um proxy que não seja IIS ou ARR (Application Request Routing) do Serviço de Aplicativo do Azure for usado, configure o proxy para encaminhar o certificado que ele recebeu em um cabeçalho HTTP. Em Startup.Configure
, adicione o código a seguir antes da chamada para app.UseAuthentication();
:
app.UseCertificateForwarding();
Configure o Middleware de Encaminhamento de Certificado para especificar o nome de cabeçalho. Em Startup.ConfigureServices
, adicione o código a seguir para configurar o cabeçalho 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 base64 (como é o caso do Nginx) defina a opção HeaderConverter
. Considere o exemplo a seguir 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 são encaminhados conforme o esperado, habilite registro em log. 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 para uma resposta do aplicativo ou para log dos cabeçalhos.
Para gravar os cabeçalhos de resposta do aplicativo, coloque o seguinte middleware terminal embutido imediatamente após a chamada para UseForwardedHeaders em 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 de no corpo da resposta. A gravação em logs permite que o site funcione normalmente durante a depuração.
Para gravar em logs em vez de no corpo da resposta:
- Injete
ILogger<Startup>
na classeStartup
conforme 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 processado, os valores X-Forwarded-{For|Proto|Host|Prefix}
são movidos para X-Original-{For|Proto|Host|Prefix}
. Quando houver vários valores em um determinado cabeçalho, o middleware de cabeçalhos encaminhados os processará na ordem inversa, da direita para esquerda. O padrão ForwardLimit
é ForwardLimit
(um), portanto, apenas o valor mais à direita dos cabeçalhos será processado, a menos que o valor de 1
seja aumentado.
O IP de remoto original da solicitação precisa corresponder a uma entrada nas listas KnownProxies
ou KnownNetworks
antes dos cabeçalhos encaminhados serem processados. Isso limita a falsificação de cabeçalho por não aceitar encaminhadores de proxies não confiáveis. Quando um proxy desconhecido é detectado, o registro em log indica o endereço dele:
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
Permitir que somente proxies e redes confiáveis encaminhem os cabeçalhos. Caso contrário, podem ocorrer ataques de falsificação de IP.