dingdonglars
dingdonglars

Reputation: 75

Blazor hosted - authorize immediately before displaying application

Can anybody give me a helping push to get my hosted Blazor application (Client, Server and Shared) to request a login immediately, before the application is initially shown. I want the experience that a user must log in before accessing the application at all.

My starting point is the Blazor Webassembly (hosted) template with Api Authorization (Individual User Accounts)

Using the Authorize attribute on either server-side actions or a client-side Razor page will not initiate the authentication flow before the specific action/page with the Authorize attribute is being requested by the user. How would I go about having the authorization flow kicked off as the first thing, before the application is even displayed for the first time?

I am sure this is possible and even trivial for somebody more savvy than me. Can anybody give me a shove in the right direction, please?

Upvotes: 2

Views: 3126

Answers (2)

Rogier
Rogier

Reputation: 1240

The Blazor Client is bootstrapped from a static index.html in the wwwroot. In the Server project this is mapped to an Endpoint in the Startup.cs, basically a catch-all to all endpoints not taken by your Razor Pages or Controllers:

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllers();
    endpoints.MapFallbackToFile("index.html");
});

For your scenario:

  1. Create a new layout in Server, say _LayoutBlazor.cshtml
  2. Re-create the contents of the index.html from the Client. Note that the _framework files from the Client are copied to the Server wwwroot upon build: :

    <app>Loading...</app>

    <script src="@Href("~/_framework/blazor.webassembly.js")"></script>

  3. Create a new Razor page and put the "Authorize" tag on it and use the _LayoutBlazor.

  4. Remove the endpoints.MapFallbackToFile("index.html"); from Startup.cs

Mark Gould has created a proof of concept here: RazorBlazor

Upvotes: 0

David Masterson
David Masterson

Reputation: 1005

I created a control RedirectToLogin.razor

@inject NavigationManager Navigation
@code {
    protected override void OnInitialized()
    {
        String thisPage = Navigation.Uri.Replace(Navigation.BaseUri, "~/");
        Navigation.NavigateTo($"Identity/Account/Login?returnUrl={thisPage}");
        base.OnInitialized();
    }
}

And then inserted it into the mainlayout.razor

<div class="container-fluid">
 <AuthorizeView>
        <Authorized>
            <NavigationLogger />
            <ContextMenuMouseClick>
                <MenuTopBar />
                <NavMenu />
                <SubPageContainer>
                    @Body
                </SubPageContainer>
            </ContextMenuMouseClick>
        </Authorized>
        <NotAuthorized>
            <RedirectToLogin />
        </NotAuthorized>
</AuthorizeView>
</div>

So when the layout is loaded and it is in the NotAuthorized state it will redirect to the login page and after authorising will return to the page it was trying to access.

Hope this helps.

Upvotes: 5

Related Questions