Thursday, January 23, 2025

Understanding Forwarded Headers Middleware in ASP.NET Core

🚀

Introduction

In modern web applications, especially those deployed behind reverse proxies (like Nginx, Apache, or cloud services like AWS and Azure), handling request headers correctly is crucial. The Forwarded Headers Middleware in ASP.NET Core ensures that proxies and load balancers pass the correct client information to the application.

This blog post will cover:
✅ What Forwarded Headers Middleware is
✅ Why it's important
✅ How to configure it in ASP.NET Core with a practical code example


🌟 What is Forwarded Headers Middleware?

When an application is deployed behind a reverse proxy, the proxy modifies request headers. For example:

  • The original client IP is replaced with the proxy server’s IP.
  • The HTTPS scheme may be removed if the proxy forwards requests via HTTP.

To ensure your app detects the correct client details, ASP.NET Core provides the Forwarded Headers Middleware.

🔹 Headers Managed by ForwardedHeadersMiddleware

1️⃣ X-Forwarded-For → Captures the original client IP.
2️⃣ X-Forwarded-Proto → Indicates the original HTTP scheme (HTTP or HTTPS).
3️⃣ X-Forwarded-Host → Contains the original host requested by the client.


🛠️ Configuring Forwarded Headers Middleware in ASP.NET Core

Let’s see how to enable and configure Forwarded Headers Middleware in an ASP.NET Core application.

1️⃣ Install Required Packages (Optional)

If not already installed, ensure the Microsoft.AspNetCore.HttpOverrides package is added:

dotnet add package Microsoft.AspNetCore.HttpOverrides

2️⃣ Configure Forwarded Headers Middleware in Program.cs

Modify your Program.cs file to include the middleware:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// 🌟 Enable Forwarded Headers Middleware
var options = new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};

// 🔹 (Optional) Allow Known Proxies
options.KnownProxies.Add(System.Net.IPAddress.Parse("192.168.1.100")); 

app.UseForwardedHeaders(options);

// Sample Endpoint to Check Headers
app.MapGet("/", (HttpContext context) =>
{
    var clientIP = context.Connection.RemoteIpAddress?.ToString();
    var originalIP = context.Request.Headers["X-Forwarded-For"].ToString();
    var originalScheme = context.Request.Headers["X-Forwarded-Proto"].ToString();

    return Results.Json(new
    {
        ClientIP = clientIP,
        ForwardedFor = originalIP,
        ForwardedProto = originalScheme
    });
});

app.Run();

🔍 Understanding the Code

🔹 ForwardedHeadersOptions → Specifies which headers to process (X-Forwarded-For, X-Forwarded-Proto).
🔹 KnownProxies → Lists trusted proxies (important for security).
🔹 UseForwardedHeaders(options) → Enables the middleware before other request-processing middleware.
🔹 HttpContext.Request.Headers → Reads the forwarded headers inside an API endpoint.


⚡ Testing Forwarded Headers in Postman or Curl

You can simulate forwarded headers using Postman or cURL:

curl -H "X-Forwarded-For: 203.0.113.42" -H "X-Forwarded-Proto: https" http://localhost:5000

Expected Response (Example Output)

{
    "ClientIP": "::1",
    "ForwardedFor": "203.0.113.42",
    "ForwardedProto": "https"
}

📌 Best Practices

1️⃣ Only trust known proxies → Use KnownProxies or KnownNetworks to avoid spoofing risks.
2️⃣ Enable forwarding at the right stage → Configure before authentication middleware.
3️⃣ Use middleware only behind a proxy → Avoid unnecessary header processing in development.


🎯 Conclusion

The Forwarded Headers Middleware is essential for handling reverse proxy headers in ASP.NET Core applications. It ensures that the application correctly identifies the client IP address and scheme, improving security and logging accuracy.

🔥 Key Takeaways:
✅ Enables handling of X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host.
✅ Necessary for reverse proxy setups (e.g., Nginx, Cloudflare, AWS).
✅ Always configure trusted proxies for security.

👉 Have any questions? Drop them in the comments below! 🚀

No comments :