http-libs
↑↓ navigate select esc close
GitHub

Forwarded Headers overview

DamianH.Http.ForwardedHeaders provides standalone RFC 7239 Forwarded header parsing and trusted-proxy middleware for ASP.NET Core on .NET 10.

ASP.NET Core's built-in UseForwardedHeaders reads X-Forwarded-*, not RFC 7239. This library processes Forwarded directly, keeping each hop's parameters together. It is not a legacy-header adapter and never translates, merges, prefers, or falls back to X-Forwarded-*. RFC 7239 is not an RFC 8941 Structured Field; this package does not depend on the StructuredFieldValues library.

Installation

Run in the consuming project directory:

dotnet add package DamianH.Http.ForwardedHeaders

The parser and middleware ship in the same package, which has a Microsoft.AspNetCore.App framework reference. Even a parser-only application requires the ASP.NET Core runtime. There is no public serializer in v1.

One local proxy: quick start

using DamianH.Http.ForwardedHeaders;
using Microsoft.AspNetCore.Http.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddForwarded(options =>
{
options.Parameters = ForwardedParameters.For | ForwardedParameters.Host
| ForwardedParameters.Proto;
options.ForwardLimit = 1;
// Retain the defaults: KnownProxies = ::1, KnownIPNetworks = 127.0.0.0/8.
options.AllowedHosts.Add("localhost");
});
var app = builder.Build();
app.UseForwarded();
app.UseRouting();
app.MapGet("/request", (HttpRequest request) => request.GetEncodedUrl());
app.Run();

Use this trust configuration only for a local proxy and control direct client access. Register forwarding early, before routing, HTTPS redirection, authentication, authorization, and anything that generates external URLs. AddForwarded uses the options system and validates at startup; middleware snapshots its configuration. Alternatively, use app.UseForwarded(new ForwardedOptions { Parameters = ForwardedParameters.Proto }) with explicitly configured trust for your deployment. Do not register both forms.

Before deployment, read proxy configuration and deployment safety, especially trust-all behavior and incompatibility with UseForwardedHeaders on the same request. PathBase is a separate, nonstandard opt-in; diagnostics describes malformed input handling and trusted observations.

Run the sample

The ASP.NET Core sample enables For | Host | Proto | PathBase, trusts the loopback defaults, accepts one hop, and allowlists localhost. From the repository root:

dotnet run --project forwarded-headers\samples\AspNetCoreSample --urls http://127.0.0.1:5080

In another PowerShell 7.3+ window (with standard native argument passing), simulate a local proxy using curl.exe:

curl.exe -H 'Forwarded: for=192.0.2.60;host="localhost:8443";proto=https;pathbase="/gateway"' http://127.0.0.1:5080/request

The response URL is https://localhost:8443/gateway/request, with effective remote IP 192.0.2.60 and port 0. The actual endpoint path remains /request. The sample returns neither the raw header nor the proxy chain.

Build or test this product using the shared repository build helpers, from the repository root:

dotnet run forwarded-headers\build.cs -- build
dotnet run forwarded-headers\build.cs -- test

For parsing without middleware, see direct parser use.