Steven McLintock
Steven McLintock

Reputation: 65

Sign out a user using AuthenticationStateProvider and set User.Identity.IsAuthenticated to false using Blazor

I've inherited a website written in Blazor and .NET Core 3.1, and I need to provide a "Logout" button to the user. The website uses a custom implementation of AuthenticationStateProvider, with the following GetAuthenticationStateAsync() method:

public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
    ClaimsIdentity identity = new ClaimsIdentity();

    if (_currentUser != null)
    {
        identity = GenerateClaimsForCurrentUser();
    }
    else
    {
        try
        {
            var user = await sessionStorage.GetItemAsync<Credentials>("User");
            if (user != null && await IsAuthentic(user))
            {
                _currentUser = await UserInfo(user);
                identity = GenerateClaimsForCurrentUser();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    return new AuthenticationState(new ClaimsPrincipal(identity));
}

To verify the user is logged in, the code is:

AuthenticationState authState = await authenticationState.GetAuthenticationStateAsync();
ClaimsPrincipal principal = authState.User;

if (principal.Identity.IsAuthenticated)
{
    ...
}

The problem is in the Logout() method I've written, which is executed when the "Logout" link is clicked. I'm removing the "User" session from Blazor's session storage, but when principal.Identity.IsAuthenticated is called, it's still returning as true?

Does anyone know how I can set IsAuthenticated to false when logging out?

Upvotes: 5

Views: 4982

Answers (1)

enet
enet

Reputation: 45586

In principle, your GetAuthenticationStateAsync method should be similar to this:

 public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var token = await GetTokenAsync();
        var identity = string.IsNullOrEmpty(token)
            ? new ClaimsIdentity()
            : new ClaimsIdentity(GenerateClaimsForCurrentUser(), "jwt");
        return new AuthenticationState(new ClaimsPrincipal(identity));
    }

Note: The GetTokenAsync method retrieves the JWT token from the local storage. If it's empty, you create a new ClaimsIdentity object with no claims. If it's not empty, you create a new ClaimsIdentity object that contains the claims you provide to it, and this object is passed to the ClaimsPrincipal’s constructor.

Upvotes: 7

Related Questions