Jake L
Jake L

Reputation: 83

.NET 5 Blazor wasm Standalone with authentication library log out issue

As the Microsoft docs describe, I've followed the security setup for the authentication via Google.

I'm able to login, but keep getting the error while trying to log out:

My URL gets redirected to:

https://localhost:5001/authentication/logout-failed?message=The%20logout%20was%20not%20initiated%20from%20within%20the%20page.

And I receive the following error:

There was an error trying to log you out: ''

My log out code is pretty basic:

Log out button and navigation:

<AuthorizeView>
            <Authorized>
                <button class="nav-link" @onclick="(e) => SignOut(e)">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="24px" height="24px"><path d="M0 0h24v24H0z" fill="none" /><path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z" /></svg>
                </button>
            </Authorized>
        </AuthorizeView>

private async Task SignOut(MouseEventArgs args)
    {
        await SignOutManager.SetSignOutState();
        NavManager.NavigateTo("/authentication/logout", true);
    }

Authentication page

@page "/authentication/{action}"
@code {
    [Parameter]
    public string Action { get; set; }

If I understand correctly this should suffice to logout.

What am I doing wrong?

Thank you for your time.

EDIT

My AppSettings are configured as:

"Authentication": {
    "Google": {
      "Authority": "https://accounts.google.com/",
      "ClientId": "XXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com",
      "ClientSecret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "PostLogoutRedirectUri": "https://localhost:5001/authentication/logout-callback",
      "RedirectUri": "https://localhost:5001/authentication/login-callback",
      "ResponseType": "id_token",
    }
}

which is called by my program.cs file as:

builder.Services.AddOidcAuthentication(options =>
            {
                builder.Configuration.Bind("Authentication:Google", options.ProviderOptions);
            });

I've modified my code:

NavManager.NavigateTo("/authentication/logout", true);

To

Navigation.NavigateTo("authentication/logout");

This did not change anything. BUT YOU STILL HAVE TO USE IT LIKE THAT.

My console log is printing the following info message:

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization failed. These requirements were not met: DenyAnonymousAuthorizationRequirement: Requires an authenticated user.

EDIT 2

IMPORTANT missing information

My MainLayout.razor is configured as:

@inherits LayoutComponentBase

@using DoIt.ComponentLibrary.Modal;

<AuthorizeView>
    <Authorized>
        <Modal />
        <NavMenu />
        <main>
            @Body
        </main>
    </Authorized>
    <NotAuthorized>
        <RedirectToLogin></RedirectToLogin>
        @Body
    </NotAuthorized>
</AuthorizeView>

Upvotes: 2

Views: 1535

Answers (2)

enet
enet

Reputation: 45764

@inherits LayoutComponentBase

@using DoIt.ComponentLibrary.Modal;

<AuthorizeView>
    <Authorized>
        <Modal />
        <NavMenu />
        <main>
            @Body
        </main>
    </Authorized>
    <NotAuthorized>
        <RedirectToLogin></RedirectToLogin>
        @Body
    </NotAuthorized>
</AuthorizeView>

The only issue I see in your code is the use of @Body in the NotAuthorized delegate. It shouldn't have been there in the first place. The issue is that after you logout the NotAuthorized delegate is executed, redirect to the login omponent, immediately after which the rendering system tries to render the Index component, as it sees the @Body property, but alas, you are not authorized to view the Index page... I don't know what made you use it there, but of course you should remove it. As for the NavMenu; there is no issue with this, and it should remain there as part of the rendering of the MainLayout

Upvotes: 2

Jake L
Jake L

Reputation: 83

My MainLayout.razor is configured as:

@inherits LayoutComponentBase

@using DoIt.ComponentLibrary.Modal;

<AuthorizeView>
    <Authorized>
        <Modal />
        <NavMenu />
        <main>
            @Body
        </main>
    </Authorized>
    <NotAuthorized>
        <RedirectToLogin></RedirectToLogin>
        @Body
    </NotAuthorized>
</AuthorizeView>

under my NavMenu component I configured the logout functionality as mentioned:

    <AuthorizeView>
            <Authorized>
                <button class="nav-link" @onclick="(e) => SignOut(e)">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="24px" height="24px"><path d="M0 0h24v24H0z" fill="none" /><path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z" /></svg>
                </button>
            </Authorized>
        </AuthorizeView>

private async Task SignOut(MouseEventArgs args)
    {
        await SignOutManager.SetSignOutState();
        NavManager.NavigateTo("/authentication/logout", true);
    }

The issue here is:

  1. I press logout
  2. Page gets navigated to /authorization/logout
  3. The application logs out -> During this process the gets removed because I don't have the permissions anymore to be viewing this component.
  4. The log out function is not completed completely and is interrupted as the calling component is removed from the UI.
  5. The mentioned error appears

-> This seems to me what is happening. I couldn't find documentation which confirms this as the related docs to this flow are very limited.

I fixed this by Getting the NavMenu AND Body component out of the AuthorizeView component.

Hope it helps.

EDIT

The real solution can be found in the description explained by @enet

Upvotes: 0

Related Questions