ForwardedHeaders 主要是用于反向代理的场景,网站应用经常依赖多层服务器和代理来处理传入请求,这可能导致请求头在传输过程中被修改或丢失。我们可以通过 ForwardedHeaders 来处理多层代理,在 ASP.NET Core 中我们可以使用 ForwaredHeaders
中间件来处理 ForwaredHeaders 从而在程序里获取到用户的实际请求信息,尤其是获取用户的请求 IP 时如果使用了反向代理又不考虑 forwarded header 大概率会出问题
当客户端向服务器发出请求时,它包含各种头部信息,这些信息提供了关于请求的客户端IP地址、用户代理等的信息。然而,当请求经过中间服务器或代理时,这些头部信息可能会被修改或删除。这可能会对应用程序造成问题,特别是对那些依赖这些头部信息的应用程序来说。
Forwarded headers是在 HTTP 请求中添加的一组特殊头部,用于传递关于客户端和代理之间连接的信息。这些头部可以包含客户端的IP地址、代理服务器的IP地址、协议(HTTP或HTTPS)以及其他相关的元数据。
使用 Forwarded headers 的目的是为了解决代理服务器转发请求时可能引起的一些问题。例如,当客户端通过多个代理服务器发送请求时,传统的HTTP头部中的信息可能会被覆盖或丢失,导致无法正确追踪请求的源头。
使用Forwarded headers的注意事项包括:
ASP.NET Core 的 Forwarded Headers 中间件允许您配置框架如何处理转发的头部信息。它使您能够从代理添加的头部信息中提取原始值,并相应地更新 HttpContext。
使用 Forwarded headers 可以提供更准确和可靠的请求追踪和连接信息.
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.All;
});
var app = builder.Build();
app.MapGet("/", (HttpContext context) => new
{
ForwardedHeaders = context.RequestServices.GetRequiredService<IOptions<ForwardedHeadersOptions>>().Value
.ForwardedHeaders.ToString(),
ConnectIp = context.Connection.RemoteIpAddress?.ToString(),
RequestHeaders = context.Request.Headers.ToDictionary(h => h.Key, h => h.Value.ToString()),
Url = context.Request.GetDisplayUrl()
});
await app.RunAsync();
我们可以使用 app.UseForwarededHeaders()
来显式地使用 Forwarded headers 中间件,也可以通过配置 ASPNETCORE_FORWARDEDHEADERS_ENABLED
环境变量来配置启用 forwarded headers 中间件
我们模拟反向代理的请求,设置 forwareded headers 请求上前面的 API
forwarded-headers-enabled
可以看到 response 返回的 IP 不是 localhost, url 也不是请求的 localhost 而是从 forwarded header 转换之后的 amazingdotnet.dev
之前只支持 X-Forwarded-Host
/X-Forwarded-Proto
/X-Forwareded-For
,在 .NET 8 里支持了 X-Forwarded-Prefix
X-Forwareded-Host
: Host
X-Forwarded-Proto
: Schema/Protocal
X-Forwarded-For
: IP
X-Forwarded-Prefix
: BasePath
在使用 Forwarded Headers 中间件时,需要考虑安全性方面的影响。确保只信任来自受信任的代理的头部信息,并在使用之前对值进行验证。
此外,要注意 Forwarded Headers 中间件可能会引入一些性能开销,因为需要额外的处理来处理转发的头部信息。需要评估对应用程序性能的影响,并进行相应的调整。