Blazor Web Assembly (wasm) won't expire client side cookie until page is refreshed

Viewed 1033

I am using the lastest .NET 5 Blazor Web Assembly Core Hosted template available in Visual Studio 2019. It already has support for authentication out of the box.

The issue is that I can expire the Cookie on the .NET Hosted (server) side like this in Startup.cs in the method ConfigureServices(IServiceCollection services):

  services.ConfigureApplicationCookie(options => 
        {
            options.AccessDeniedPath = "/Identity/Account/AccessDenied";
            options.Cookie.Name = "MyCookie";
            options.Cookie.HttpOnly = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
            options.LoginPath = "/Identity/Account/Login";
            options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
            options.SlidingExpiration = true;     
        });

However, my requirement is that when the session expires after 20 minutes, the user should be asked to login again. My problem with this is that the cookie only expires if the browser is closed or the user hits reload. In the meantime, I can hit all the controllers even if they have the [Authorize] tag in them. The ideal situation is when the user calls a controllers then it redirects to login.

enter image description here Cookies are created after login.

enter image description here When time has passed cookies are gone, but the user still has all permissions.

1 Answers

Add a Utilities.js javaScript file to wwwroot/js in the Client Project with the following function.

function initializeInactivityTimer(dotnetHelper) {
var timer;
document.onmousemove = resetTimer;
document.onkeypress = resetTimer;

function resetTimer() {
    clearTimeout(timer);
    timer = setTimeout(logout, 1200000);
}

function logout() {
    dotnetHelper.invokeMethodAsync("Logout");
}}

Make sure you add it to the end of wwwroot/index.html

 <script src="js/Utilities.js"></script>

In the Server project in MainLayout.razor add the following method

[JSInvokable]
public async Task Logout()
{
    var authState = await AuthenticationState;
    if (authState.User.Identity.IsAuthenticated)
    {
        await SignOutManager.SetSignOutState();

        NavigationManager.NavigateTo("authentication/logout");
    }
}

Make sure you add to the top the MainLayout.razor

@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IJSRuntime js
@inject SignOutSessionStateManager SignOutManager

Also add this Cascading Parameter

[CascadingParameter]
public Task<AuthenticationState> AuthenticationState { get; set; }

Still on MainLayout.razor on Task OnInitializedAsync(), call the javascript function like this:

await js.InvokeVoidAsync("initializeInactivityTimer",  DotNetObjectReference.Create(this));

Keep all modifications on StartUp.cs. They are good for when the user reloads or closes the browser. This js function will log out the user if there is no mouse movement or keys are pressed.

Reference

https://www.youtube.com/watch?v=cOV0uV_E6bU

https://github.com/gavilanch/BlazorMovies/tree/master/ASP.NET%20Core%205/Module%207%20-%20Security

Related