Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

How to keep actual AuthenticationState in C# Blazor Server App?

$
0
0

I have a custom AuthenticationStateProvider service that stores credentials in localStorage.

Program.cs:

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();

AuthStateProvider.cs (CustomAuthStateProvider):

Save to storage:

public async Task UpdateAuthenticationState(string jwtToken = null) {    ClaimsPrincipal claimsPrincipal = Claims.Anonymous;    if (jwtToken != null)     {        SecurityToken securityToken;        var claims = JwtHandler.ValidateToken(jwtToken, await _tokenValidator.GetValidationParameters(), out securityToken);        if (securityToken != null && claims != null)         {            claimsPrincipal = claims;            await _localStorage.SetItemAsync("AuthToken", jwtToken);        }    }    else     {        await _localStorage.RemoveItemAsync("AuthToken");    }    NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(claimsPrincipal)));}

Get from storage:

public override async Task<AuthenticationState> GetAuthenticationStateAsync() {        try {            //await Task.Delay(5000);            var userSessionStorageResult = await _localStorage.GetItemAsync<string>("AuthToken");            if (userSessionStorageResult != null) {                SecurityToken securityToken;                var claims = JwtHandler.ValidateToken(userSessionStorageResult, await _tokenValidator.GetValidationParameters(), out securityToken);                if (securityToken != null && claims != null)                    return await Task.FromResult(new AuthenticationState(claims));            }        } catch { }        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(Claims.Anonymous)));        return await Task.FromResult(new AuthenticationState(Claims.Anonymous));    }

App.razor:

<CascadingAuthenticationState><Router AppAssembly="@typeof(App).Assembly"><Found Context="routeData"><AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /><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>

Index.razor (this page):

@page "/"@attribute [Authorize]<PageTitle>Index</PageTitle><Button Color="ButtonColor.Primary" @onclick="OnlyAuthButton">OnlyAuth</Button>@code{    [Inject] protected ToastService ToastService { get; set; }    private async Task OnlyAuthButton() {        ToastService.Notify(new ToastMessage(ToastType.Danger, Loc["Some error occured"]));    }}

When I update authentication state, it performs NotifyAuthenticationStateChanged that rerenders the Blazor components and all works good.

Authenticated

But when I delete token from local storage manually and click button, Blazor app does not check authentication state and works like I'm authorized until I reload page.

Unauthenticated by deleting token from local storage

After reloading by F5

Is there any common solutions such as middleware for actions on Razor Components with SignalR that can validate authentication state. For example I click button => Blazor checks authentication => Blazor execute ButtonClick handler method. Of course I can retrieve AuthState in begin of handler but it's mean that I need to place this action in each handler in application and this sounds not good.

PS: it's necessary to use local storage instead cookie because I need crosstab application


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>