Home > Software engineering >  Best approach for hiding Blazor WebAssembly app behind login wall
Best approach for hiding Blazor WebAssembly app behind login wall

Time:11-05

I need to build an ASP.NET Core hosted Blazor Webassembly app (.NET 6) where all of the app functionality is hidden behind a login wall but I'm not sure how best to achieve this. For authentication/authorisation I'm using ASP.NET Identity and IdentityServer.

So far I've created a new Razor component called Login.razor which simply contains a link that triggers the built in authentication process:

<a href="authentication/login">Log in</a>

This component has the @page directive "/" so it's the first 'page' the user lands on when they go to the app.

This works fine, but once the user has then successfully logged in they are redirected to the return URL as part of the .NET Identity process, which in this case is a now useless login page.

I don't want to just replace the return URL in the Identity pages and redirect the user to another specific page because I think the return URL will be really useful in situations where the user has been sent a link to a specific page. For example, if I try and navigate to a protected resource like mywebsite.com/fetchdata without logging in first, it triggers whatever authentication magic Blazor comes shipped with, gets the user to log in and then redirects them to /fetchdata once they've successfully done so. I want to keep that functionality.

What do I need to do to get the server to redirect to another page (e.g. "/index") if the user has come from the Login.razor component? Or am I just approaching all of this in completely the wrong way? Any advice much appreciated.

CodePudding user response:

Create a new component called RedirectToLogin and add this code:

@inject NavigationManager Navigation

@code {
    protected override void OnInitialized()
    {
        Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}");
    }
}

Then change your App.razor to be like this:

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    @if (context.User.Identity?.IsAuthenticated != true)
                    {
                        <RedirectToLogin />
                    }
                    else
                    {
                        <p role="alert">You are not authorized to access this resource.</p>
                    }
                </NotAuthorized>
            </AuthorizeRouteView>
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

Now when an unauthenticated user tries to access a protected page he will be automatically redirected to authentication/login?returnUrl=....

Documentation

CodePudding user response:

You can implement this in various ways. Here's one way I'd do that when using WebAssembly Blazor App hosted...

The following design below describes how to enable anonymous access to the Index page only, while requiring the user to login in order to access the Counter and FetchData pages:

1 Add the following to your _Imports.razor file:

@using Microsoft.AspNetCore.Authorization
   @attribute [Authorize]

This allow access only to authenticated users.

2 Add the following to your Index.razor file:

 @using Microsoft.AspNetCore.Authorization
    @attribute [AllowAnonymous]

to allow anonymous access to the Index page.

3 Also add the following setting to the Authentication.razor file:

 @attribute [AllowAnonymous]

Testing: Run your app. Click on the Counter link... You are redirected to the Login page if not authenticated... authenticate yourself...You are now being redirected to the Counter page.

Note: If you want your user to be redirected to the Login page when running the app; that is, not being able to access the Index page unless authenticated, just remove @attribute [AllowAnonymous]

I won't do that like that, but some people prefer it that way.

  • Related