ASP.NET Core Navigation Manager not using `base href` value

Viewed 308

I have a Blazor WebAssembly app that is hosted on an internal server on the company network, for example at: https://internal.domain.com/app. The app is accessible externally through a reverse proxy at: https://external.domain.com/app.

In the Blazor/C# code, we are using the .NET Core NavigationManager to set up some redirects, paths, etc. which work perfectly when accessed internally. But we are facing a problem when accessed externally since the NavigationManager's URIs values are returned using the internal server address.

We have some code that sets the HTML <base> element href value to the external address which the NavigationManager should pickup. However, the values returned/expected by the nav manager are still the internal address which causes issues for our paths and redirects. As stated in the documentation, the NavigationManager.BaseUri typically:

... corresponds to the href attribute on the document's <base> element.

I cannot find additional information on the above statement or how/if the nav manager's base URI can be initialized.

Does anyone know how the .NET Core NavigationManager makes use of the HTML Base element? And how it can be set to use the external address in this scenario?

TIA

EDIT:

Below is a sample code for the Login scenario:

  • In the index.html file includes some JavaScript to setup the <base> element and the corresponding external URL. When inspecting the page markup the base href value is set as expected, using the external URL.
  • The App.razor points to any unauthenticated requests to the RedirectToLogin.razor component.
  • The latter redirects to an external authentication provider passing the return URL to the provider to navigate to once logged in. The return URL uses Navigation.Uri (absolute value similar to Navigation.BaseUri). Based on the documentation this should use the base href value but it does not pick up the value set in index.html (external URL).
  • Navigation fails after the login provider navigates to the internal app URL.

wwwroot/index.html:

<head>
<script type="text/javascript">
    var appBase = document.createElement('base');
    appBase.href = "/app/";
    
    //not actual if condition, but same logic
    if (window.location.href.startsWith("https://external.domain.com")) {
        appBase.href = "https://external.domain.com/app/";
    }

    document.head.appendChild(appBase);
</script>
</head>

App.razor

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    @if (!context.User.Identity.IsAuthenticated)
                    {
                        <RedirectToLogin />
                    }
                </NotAuthorized>
            </AuthorizeRouteView>
        </Found>
    </Router>
</CascadingAuthenticationState>

RedirectToLogin.razor

@inject NavigationManager Navigation
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@code {
    protected override void OnInitialized()
    {
        var uri = Navigation.Uri;

        if (!uri.EndsWith("/"))
            uri += "/";

        Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(uri)}");
    }
}
1 Answers
Related