2

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?

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! I got this to work. The out-of-the box Blazor hosted client template already creates a RedirectToLogin.razor control. However, different to yours, the default RediriectToLogin redirects to the page Authentication.razor, which is also provided by the template. I wanted to preserve this and thus had to add a new, empty Layout to be used by the Authentication.razor page. Otherwise the Authentication page would load the MainLayout.razor again and RedirectToLogin and off it went in a silly loop :-) I got one step further in this adventure, thanks for your help!
OnInitialized throws an NavigationException. To fix it, I used the OnAfterRenderedAsync() method.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.