Blog Post

IIS Support Blog
3 MIN READ

How to Properly Configure IIS Reverse Proxy for ASP.NET Core Applications Secured with Entra ID

sainathreddy's avatar
sainathreddy
Icon for Microsoft rankMicrosoft
Mar 04, 2025

If you’ve ever worked on an ASP.NET Core application protected with Entra ID, you might have encountered an issue where the backend server URL appears as the redirect URI instead of the IIS Reverse Proxy URL. 

 

 

This is because ASP.NET Core applications use the backend server’s hostname to generate the redirect URI. While this behavior is the default, it can be problematic.

While you can work around this by manually setting the redirect URI to the ARR/IIS Reverse Proxy endpoint in your code as follows:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

builder.Services.Configure<OpenIdConnectOptions>(options =>
{
    options.Events.OnRedirectToIdentityProvider = context =>
    {
        context.ProtocolMessage.RedirectUri = "https://arr.local.lab";
        return Task.FromResult(0);
    };
});

 

It isn’t the most elegant solution, especially in environments where configuration changes might often be required. Instead, using Forwarded Headers offers a cleaner, more scalable approach.

In this post, I’ll walk you through how to resolve this issue using Forwarded Headers.

ASP.NET Core provides a ForwardedHeaders Middleware , which reads headers such as X-Forwarded-Host and X-Forwarded-Proto. These headers replace values in HttpContext such as HttpContext.Request.Host and HttpContext.Request.Scheme. By passing these headers appropriately from IIS Reverse Proxy, we can resolve the redirect URI issue.

But IIS reverse proxy or server farms doesn't send X-Forwarded-Host & X-Forwarded-Proto headers by default. You’ll need to configure IIS to include these headers using the URL Rewrite feature. To do so, follow these steps:

  • Set Server Variables
    • Open the URL Rewrite module in the IIS Manager Console and Select View Server Variables.

    • Add following Server Variables:
      • HTTP_X_Forwarded_Host
      • HTTP_X_Forwarded_Proto
  •  Edit Inbound Rules
    • Once Server Variables are added, select the concerned reverse proxy inbound rule and select Edit under Inbound rules in Actions Pane. 
  • Add the Server Variables to the inbound rule:
    • Map HTTP_X_Forwarded_Host to {HTTP_HOST}
    • Map HTTP_X_Forwarded_Proto to https

Once IIS is configured to pass forwarded headers, the application needs to process them. Add ForwardedHeaders Middleware in your ASP.NET Core application and configure ForwardedHeadersOptions as follows:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddAuthorization(options =>
{
    // By default, all incoming requests will be authorized according to the default policy.
    options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages()
    .AddMicrosoftIdentityUI();

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.160.7.4")); // Reverse Proxy IP address
    options.ForwardedHeaders =
            ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
});

var app = builder. Build();

app.UseForwardedHeaders(); // ForwardedHeaders Middleware

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapStaticAssets();
app.MapRazorPages()
   .WithStaticAssets();
app.MapControllers();

app.Run();

 

Note:

  • Order of the Middleware is important. Ensure ForwardedHeaders Middleware is called before any other middleware in the pipeline.
  • Make sure to add the IP address of your ARR/IIS Reverse Proxy to the KnownProxies list. Alternatively, you can use KnownNetwork to set IP range.

With these configurations, X-Forwarded-Host and X-Forwarded-Proto headers sent from IIS Reverse Proxy will replace the Host and Scheme in HttpContext. This ensures that the redirect URI correctly points to the IIS Reverse Proxy endpoint, resolving the issue seamlessly.

 

Further Reading:

Refer to these resources for more information:

Configure ASP.NET Core to work with proxy servers and load balancers | Microsoft Learn

Setting HTTP request headers and IIS server variables | Microsoft Learn

IIS Server Variables | Microsoft Learn

 

Hope this guide helps! 

Updated Mar 04, 2025
Version 1.0
No CommentsBe the first to comment