Can't login on Blazor WebAssembly

485 Views Asked by At

I am trying to use ngrok to access my Blazor WebAssembly application, but I am unable to login.

There was an error trying to log you in: 'Network Error'

Inspecting the calls I noticed that he tries to access the Url: http://localhost/.well-known/openid-configuration instead http://abcdefgh.ngrok.io/.well-known/openid-configuration

Is there any way to fix this via boot parameters?

2

There are 2 best solutions below

1
On

You need to update your Progam.cs file and set the HttpClient.BaseAddress to use the proper URI.

Using Blazor WASM standalone:

builder.Services.AddHttpClient(
"Private.ServerAPI", 
client => client.BaseAddress = new Uri("https://api.myapp.com"));

OR, if you are using Blazor-hosted WASM:

builder.Services.AddHttpClient(
"Private.ServerAPI", 
client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));
0
On

If you are using WASM hosted in ASPNET then the OpenID configuration URL is taken from the 'authority' value returned by the call to /_configuration/YourApp.Client (assuming you're using the standard template). Because ngrok is a reverse proxy the server side knows nothing about the URL the client is using and it assumes the request was sent to localhost.

You can manipulate the authority URL in OidcConfigurationController but then you just get the same issue with the endpoints returned from /.well-known/openid-configuration.

To properly fix it the request pipeline needs to be made aware of the URL the client is using.

I added this to my Startup.cs:

   public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
   {
        //for using IdentityServer with ngrok
        if (env.IsDevelopment())
        {
            app.Use(async (ctx, next) =>
            {
                if (ctx.Request.Host.HasValue  && ctx.Request.Headers.ContainsKey("X-Original-Host") && ctx.Request.Headers["X-Original-Host"].First().ToLower().EndsWith(".ngrok.io"))
                {
                    ctx.Request.Scheme = ctx.Request.Headers["X-Forwarded-Proto"];
                    ctx.Request.Host = new HostString(ctx.Request.Headers["X-Original-Host"]);
                }

                await next();
            });

            app.UseForwardedHeaders(); //https://learn.microsoft.com/en-gb/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-5.0
        }

This must go at the top of the HTTP request pipeline. Just app.UseForwardedHeaders() on it's own didn't work for me, maybe because ngrok's headers have different names.

There's an alternative answer here: https://stackoverflow.com/a/64327330/1499294 which uses SetIdentityServerOrigin(). If you prefer that method then you can combine it with the above to avoid hard-coding the host name.

Useful links:

https://github.com/IdentityServer/IdentityServer4/issues/4535

https://learn.microsoft.com/en-gb/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-5.0#iisiis-express-and-aspnet-core-module