HTTPS not working in ASP.NET Core app hosted in Caprover

641 Views Asked by At

I'm hosting an ASP.NET Core Docker web app in the open source Caprover Paas in a Linux VM and it runs fine. Using the Caprover interface, I was able to configure the site's LetsEncrypt SSL certificate and the browser shows a padlock and says connection is secure. The problem is that ASP.NET doesn't detect the app is running in Https mode and Request.IsHttps is always false. Here's my test.

index.cshtml

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

 @if (Request.IsHttps)
{
    <div class="alert alert-success"><strong>HTTPS:</strong> You are using a secure connection</div>
}
else
{
    <div class="alert alert-warning"><strong>HTTP:</strong> Your connection is NOT secure</div>
}

It always displays enter image description here

Caprover uses Docker containers and Nginx proxy server so I suspect that's the issue as Request.IsHttps returns true when running the app on my windows laptop.

This is the program.cs which is just a typical Visual studio template.

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Question is how do I configure the app to detect it's running in Https?

1

There are 1 best solutions below

0
On BEST ANSWER

As suspected, the issue is Nginx proxy server handles the encryption/decryption of https connections but when forwarding the request to the container, it uses plain http. So asp.net never sees the https connection since it's terminated at the proxy server. The solution is to forward X-Forwarded-For and X-Forwarded-Proto headers. See below modifications.

Program.cs

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();

//ADD: Configure middleware to add X-Forwarded-For and X-Forwarded-Proto headers
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    //accept all networks and proxies
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
});

var app = builder.Build();

//ADD: use ForwardedHeaders middleware
app.UseForwardedHeaders();


// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

//REMOVE: not needed as nginx proxy server handling https
//app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Here is the complete sample on Github.