I've written my first Blazor app using the server-side rendering with SignalR.
I'm having trouble with authentication.
There is a function that performs a database query. If it returns true
, the user is allowed to access the app. If it returns false
, the user is to be directed to an logon page.
I've read about some of the classes and components used to implement authentication, such as AuthorizationStateProvider
and AuthorizedView
, but I'm not clear on how I'm supposed to use them for this simple situation.
It's really very simple.
bool isAuthenticated = Helper.IsUserLoggedIn();
if (!isAuthenticated)
{
// redirect user to logon page
}
I know that I can invoke Helper.IsUserLoggedIn
, I just want to know the usual best practice for setting this up properly with the framework; I might add additional functionality later.
I've written my first Blazor app using the server-side rendering with SignalR.
I'm having trouble with authentication.
There is a function that performs a database query. If it returns true
, the user is allowed to access the app. If it returns false
, the user is to be directed to an logon page.
I've read about some of the classes and components used to implement authentication, such as AuthorizationStateProvider
and AuthorizedView
, but I'm not clear on how I'm supposed to use them for this simple situation.
It's really very simple.
bool isAuthenticated = Helper.IsUserLoggedIn();
if (!isAuthenticated)
{
// redirect user to logon page
}
I know that I can invoke Helper.IsUserLoggedIn
, I just want to know the usual best practice for setting this up properly with the framework; I might add additional functionality later.
2 Answers
Reset to default 0You can create your own implementation, MyCustomAuthenticationStateProvider
, inheriting from AuthenticationStateProvider
, and use the GetAuthenticationStateAsync
method within it, which will check your user's authentication status every time any .razor
page is rendered. Then, inside your component, you can use the Authorized
or NotAuthorized
tags to display content appropriately for authorized or unauthorized users.
For example:
MyCystomAuthenticationStateProvider.cs:
public class MyCustomAuthenticationStateProvider : AuthenticationStateProvider
{
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
}
Example.razor:
@page "/Example"
<AuthorizeView>
<Authorized>
You can see this text if you are authorized
</Authorized>
<NotAuthorized>
You can see this text if you are not authorized
</NotAuthorized>
</AuthorizeView>
Useful links to the full implementation of the functionality:
https://blazorschool/tutorial/blazor-server/dotnet7/basic-authentication-764437
https://learn.microsoft/en-us/aspnet/core/blazor/security/?view=aspnetcore-8.0&tabs=visual-studio
Generally, we will use ASP.NET Core Identity to achieve the authentication and authorization in Blazor App. And ASP.NET Core Identity scaffolding adds ASP.NET Core Identity to Blazor Web Apps and Blazor Server apps. After the scaffolder adds the Identity Razor components to the app, you can customize the components to suit your app's requirements.
After that we could use the AuthorizeView
or AuthorizeRouteView
component controls the visibility of elements or navigate to the Login page based on the user’s authorization status.
For example: In the Protect page, we could use the AuthorizeView
component as below:
@page "/protected"
@using BlazorServerIdentity.Components.Account.Shared
@using Microsoft.AspNetCore.Authorization
@using BlazorServerIdentity.Data
@attribute [Authorize]
<h2>This is the protect page</h2>
<AuthorizeView>
<Authorized>
<p>Welcome, @context.User.Identity.Name!</p>
</Authorized>
<NotAuthorized>
@if (!context.User.Identity.IsAuthenticated)
{
<RedirectToLogin />
}
</NotAuthorized>
</AuthorizeView>
In the BlazorServerIdentity.Components.Account.Shared
folder (the project name is BlazorServerIdentity
) the RedirectToLogin
component content as below:
@inject NavigationManager NavigationManager
@code {
protected override void OnInitialized()
{
NavigationManager.NavigateTo($"Account/Login?returnUrl={Uri.EscapeDataString(NavigationManager.Uri)}", forceLoad: true);
}
}
When user access the protected page, it will check the user's authorization status via context.User.Identity.IsAuthenticated
, then redirect to login page.
Besides, you can also check the user status in the component's OnInitializedAsync
method:
@page "/protected"
@using Microsoft.AspNetCore.Authorization
@using BlazorServerIdentity.Data
@inject NavigationManager Navigation
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject ApplicationDbContext _dbContext
@attribute [Authorize]
<h2>This is the protect page</h2>
@code {
protected override async Task OnInitializedAsync()
{
//get the user status via AuthenticationStateProvider, you can also query the database via the _dbContext
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (!authState.User.Identity.IsAuthenticated)
{
Navigation.NavigateTo($"identity/account/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}");
}
}
}
More detail information about authentication and authorization in Blazor, see ASP.NET Core Blazor authentication and authorization
NavigationManager.NavigateTo
to navigate to the login page within theif
clause in the code above? – MrC aka Shaun Curtis Commented Mar 21 at 16:38