dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.36k stars 9.99k forks source link

NavigationManager in SSR navigates from https to http #57454

Closed Jakan closed 1 month ago

Jakan commented 1 month ago

Hi,

when I call the function NavigationManager.NavigateTo("/weather") in SSR-Mode and have published the web app (https link). An attempt is made to switch to http://.../weather using the submit function (no https).

As soon as I add @rendermode="InteractiveServer" it routes correctly to https://.../weather.

Is this known or am I doing something wrong?

javiercn commented 1 month ago

@Jakan thanks for contacting us.

It would be incredibly rare that this was a framework bug, since the framework delegates to HttpContext.Redirect.

Are you using some sort of proxy in combination with SSL termination? (Does your ASP.NET Core host receives the forwarding headers correctly?)

You can check this by adding some middleware and printing the values.

Jakan commented 1 month ago

@javiercn: Thanks for your reply.

I use Plesk. I installed the .net toolkit there and uploaded the application there via publication from Visual Studio.

On my test page, I have the following elements:

<EditForm Enhance Model="CurrentTest" OnSubmit="HandleSubmit" FormName="TestForm">
        <button type="submit" class="btn btn-primary">Save</button>
</EditForm>

As soon as I call the HandleSubmit method, this is executed:

void HandleSubmit()
{
    NavigationManager.NavigateTo("/weather");
}

That redirects me to http, even though the page uses https.

As soon as I add @rendermode InteractiveServer above, I get properly routed from https to https.

You say, "You can check this by adding some middleware and printing the values" -> you mean in blazor or on the server?

javiercn commented 1 month ago

@Jakan on the server.

app.Use((ctx,nxt) => {
  // Log the server URL or send it on a header to the response so you can see it in the browser.
  return nxt();
});
javiercn commented 1 month ago

@Jakan We can't comment on Plesk as we are not familiar with it.

This likely means that you are not forwarding the headers or capturing them. See https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-8.0

On interactive render mode the URL is populated from the browser via JS when the circuit starts, but during SSR, that's not possible, as the only information available is the HTTP request.

Is Kestrel configured to run on HTTPS? Or are you terminating HTTPS at the Plex Server layer.

Jakan commented 1 month ago

Hi,

if i set this:

app.Use((ctx, nxt) => {
    ctx.Request.Scheme = "https";
    return nxt();
});

it works... is this ok for production?

javiercn commented 1 month ago

@Jakan no.

That might seem that it works, but it can have other unexpected consequences.

You should make sure the forwarding headers are sent from the proxy if you are terminating HTTPS at other location other than kestrel. (Which I am going to assume you are, but if you are using HTTPS with Kestrel, let us know).

Start by following the guidance provided https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-8.0#forwarded-headers-middleware-order

Jakan commented 1 month ago

Hi,

thanks again :).

Plesk for Linux uses the Apache HTTP server to host websites.

I removed this: app.Use((ctx, nxt) => { ctx.Request.Scheme = "https"; return nxt(); });

Now i add the following:

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});

var app = builder.Build();

app.UseForwardedHeaders();

Without this lines i see in the developer tools: Request Headers -> https Response Headers -> http

With the lines from above i see: Request Headers -> https Response Headers -> https

... and it works.

Is this now ok for production :) ?

Greetings

javiercn commented 1 month ago

@Jakan yes.