From 0d8194a1d90630901bc431efb4708d037c5f4de5 Mon Sep 17 00:00:00 2001 From: Arne Moerman Date: Sun, 17 May 2026 22:06:16 +0200 Subject: [PATCH] Add PublicUrl support for reverse proxy handling Introduced a `PUBLIC_URL` environment variable to configure the public URL for OAuth callbacks and reverse proxy scenarios. Updated `Program.cs` to rewrite request scheme and host based on `PublicUrl`. Replaced `Microsoft.AspNetCore.Components.Authorization` with `Microsoft.AspNetCore.Components.Authentication`. Added `PublicUrl` to `appsettings.json` with a default empty value. --- deploy/portainer-stack.env.example | 3 +++ deploy/portainer-stack.yml | 1 + src/BirthList.Web/Program.cs | 14 +++++++++++++- src/BirthList.Web/appsettings.json | 3 ++- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/deploy/portainer-stack.env.example b/deploy/portainer-stack.env.example index 12d6604..e84eba7 100644 --- a/deploy/portainer-stack.env.example +++ b/deploy/portainer-stack.env.example @@ -1,6 +1,9 @@ # Required for SQL Server container and app DB connection SA_PASSWORD=ChangeThisToAStrongPassword123! +# Public URL of the site (used to fix OAuth callbacks behind a reverse proxy) +PUBLIC_URL=https://yourdomain.example.com + # Optional OAuth (leave empty to disable provider at runtime) GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= diff --git a/deploy/portainer-stack.yml b/deploy/portainer-stack.yml index a108b5c..9090746 100644 --- a/deploy/portainer-stack.yml +++ b/deploy/portainer-stack.yml @@ -22,6 +22,7 @@ services: - Smtp__Password=${SMTP_PASSWORD} - Smtp__FromAddress=${SMTP_FROM_ADDRESS} - Smtp__FromName=${SMTP_FROM_NAME} + - PublicUrl=${PUBLIC_URL} depends_on: - mssql networks: diff --git a/src/BirthList.Web/Program.cs b/src/BirthList.Web/Program.cs index 9c267c0..bf213af 100644 --- a/src/BirthList.Web/Program.cs +++ b/src/BirthList.Web/Program.cs @@ -3,7 +3,7 @@ using BirthList.Web.Authorization; using BirthList.Web.Configuration; using BirthList.Web.Features.Registries; using BirthList.Web.Services; -using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Authentication; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; @@ -159,6 +159,18 @@ else } app.UseForwardedHeaders(); + +var publicUrl = app.Configuration["PublicUrl"]; +if (!string.IsNullOrWhiteSpace(publicUrl) && Uri.TryCreate(publicUrl, UriKind.Absolute, out var publicUri)) +{ + app.Use(async (context, next) => + { + context.Request.Scheme = publicUri.Scheme; + context.Request.Host = new Microsoft.AspNetCore.Http.HostString(publicUri.Host, publicUri.IsDefaultPort ? -1 : publicUri.Port); + await next(); + }); +} + app.UseHttpsRedirection(); app.UseStaticFiles(); diff --git a/src/BirthList.Web/appsettings.json b/src/BirthList.Web/appsettings.json index 45645ce..6eb8155 100644 --- a/src/BirthList.Web/appsettings.json +++ b/src/BirthList.Web/appsettings.json @@ -38,5 +38,6 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "PublicUrl": "" }