I am using WSO2 Asgardeo authentication for my Blazor WebAssembly hosted application.
The application is hosted on an internal server:https://test.myapp.local
I have configured a reverse proxy on another IIS server that is exposed to the internet:https://test.myapp.com
When I access the application directly through the internal server (test.myapp.local), authentication works correctly.
For reference, I have already configured the redirect URLs for both domains (.local and .com) in WSO2 Asgardeo.
However, when accessing the application through the reverse proxy (test.myapp.com), authentication does not work.
Could you please help identify what might be causing this issue?
Program.cs
using Microsoft.AspNetCore.Antiforgery;using Microsoft.AspNetCore.Authentication;using Microsoft.AspNetCore.Authentication.Cookies;using Microsoft.AspNetCore.Authentication.OpenIdConnect;using Microsoft.AspNetCore.HttpOverrides;using Microsoft.AspNetCore.Mvc;using Radzen;using System.Net.Http.Headers;namespace myapp{ public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddAuthenticationStateSerialization(options => options.SerializeAllClaims = true) .AddInteractiveWebAssemblyComponents(); builder.Services.AddRadzenComponents(); var asgardeo = builder.Configuration.GetSection("Authentication:Asgardeo"); builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }).AddCookie(options =>{ options.Cookie.Name = ".Blazor.Asgardeo.Auth"; options.SlidingExpiration = true; options.Cookie.SameSite = SameSiteMode.None; options.Cookie.SecurePolicy = CookieSecurePolicy.Always;}).AddOpenIdConnect(options =>{ options.Authority = asgardeo["Authority"]; options.ClientId = asgardeo["ClientId"]; options.ClientSecret = asgardeo["ClientSecret"]; options.ResponseType = "code"; options.UsePkce = true; options.SignedOutCallbackPath = asgardeo["SignedOutCallbackPath"]; options.RemoteSignOutPath = asgardeo["RemoteSignedOutCallbackPath"]; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Clear(); foreach (var scope in asgardeo.GetSection("Scopes").Get<string[]>()) { options.Scope.Add(scope); }}); builder.Services.AddAntiforgery(options => { options.HeaderName = "X-CSRF-TOKEN"; }); builder.Services.AddResponseCaching(); builder.Services.AddCascadingAuthenticationState(); builder.Services.AddAuthorization(options => { options.FallbackPolicy = options.DefaultPolicy; options.AddPolicy("AdminOnly", policy => policy.RequireRole("dealerportal.admin")); }); builder.Services.AddControllersWithViews(); builder.Services.AddHttpContextAccessor(); builder.Services.AddHttpClient(); builder.Services.AddScoped<BusyDialogService>(); var app = builder.Build(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost }); if (app.Environment.IsDevelopment()) { app.UseWebAssemblyDebugging(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.UseAntiforgery(); app.UseResponseCaching(); app.MapGet("/login", async (HttpContext context) => { await context.ChallengeAsync( OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" }); }); app.MapGet("/logout", async (HttpContext context) => { await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); await context.SignOutAsync( OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" }); }); app.MapPost("/forcefully-logout", async (HttpContext context) => { await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); context.Response.StatusCode = StatusCodes.Status200OK; }); app.MapControllers(); app.MapStaticAssets(); app.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(Client._Imports).Assembly); app.Run(); } }}One observation I made is related to the redirection behavior.
When accessing the application internally, it correctly redirects to the Asgardeo login URL:
https://accounts.asgardeo.io/t/myappcompany/authenticationendpoint/login.do?client_id=Kx243FCccg
However, when accessing the production site through the reverse proxy, it redirects to:
https://test.myapp.com/t/myappcompany/authenticationendpoint/login.do?client_id=Kx243FCccg