I've just begun constructing a simple web assembly ASP.NET client-side web app with authentication powered by Auth0.
There are a few articles I've found walking you through the steps needed to do this, like this one: https://auth0.com/blog/what-is-blazor-tutorial-on-building-webapp-with-authentication/
Unfortunately since many of them were written it seems that Blazor client-side projects were ported from targeting .NET Core to .NET Standard and as a result it's not possible to install the NuGet Package needed: Microsoft.AspNetCore.Authentication.OpenIdConnect
Instead I found a tutorial from Microsoft that uses Microsoft.AspNetCore.Components.WebAssembly.Authentication
which wraps some Javascript code needed to handle the authentication flow:
https://learn.microsoft.com/en-us/aspnet/core/security/blazor/webassembly/standalone-with-authentication-library?view=aspnetcore-3.1
I managed to get it working but when I log out and go to log in again the app automatically authenticates without taking me to the Auth0 login page. According to the OpenID Connect specification I need to send an optional prompt
parameter set to login
to force the showing of a login screen (what I would expect as a user after logging out).
The aforementioned Microsoft.AspNetCore.Authentication.OpenIdConnect
library has the ability to set this parameter: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.openidconnect.openidconnectoptions.prompt?view=aspnetcore-3.0
The WebAssembly library from what I can tell does not: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.webassembly.authentication.oidcprovideroptions?view=aspnetcore-3.1
Does anyone know a workaround?
My Program.cs
is as follows:
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddOidcAuthentication(options =>
{
options.ProviderOptions.Authority = $"https://{builder.Configuration["Auth0:Domain"]}";
options.ProviderOptions.ClientId = builder.Configuration["Auth0:ClientId"];
options.ProviderOptions.ResponseType = builder.Configuration["Auth0:ResponseType"];
options.ProviderOptions.PostLogoutRedirectUri = "/";
});
await builder.Build().RunAsync();
}
}
I found that I need to explicitly call the logout
endpoint:
https://auth0.com/docs/api/authentication?javascript#logout
For now I have created a Logout
component and added the logic inside - I hope there is a better way (e.g. configuring this as part of AddOidcAuthentication
but I couldn't figure it out).
@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager
@inject BaseAddress BaseAddress
@inject Auth0Config Auth0Config
<AuthorizeView>
<Authorized>
<button class=@($"{CssClass} btn btn-link") @onclick=BeginSignOut>Log out</button>
</Authorized>
</AuthorizeView>
@code {
[Parameter]
public string CssClass { get; set; }
private async Task BeginSignOut()
{
await SignOutManager.SetSignOutState();
Navigation.NavigateTo($"{Auth0Config.Authority}/v2/logout?client_id={Auth0Config.ClientId}&returnTo={BaseAddress.Url}authentication/logout");
}
}