Setting up Auth0 between Blazor WASM with ASPNET Core

I have experience setting up Auth0 with Xamarin.Forms, but I’m taking my first stab at configuring a Blazor Client Side (WASM) app to work with Auth0 and also authenticate against my aspnet core webapi backend.

So far I have followed a number of blog posts (too many to list), but as the Blazor landscape is changing so much, I’m no longer confident in their relevance. Here’s the scenario that I have personally at a high level.

Data stored in MongoDB Atlas
API Hosted in Azure using aspnet core webapi (net5.0)
Blazor WASM also on Azure, also on net5.0
Future (Maui iOS/Android)

The goal that I have is to have dynamic Roles, stored in MongoDB along with the rest of my Tenant information, and to have all client side apps (Blazor & Maui) be able to authenticate against Auth0, receive an access token and refresh token, and be able to access protected data in my API.

This all seems really straightforward, but I’m really struggling with getting everything to mesh.

note: I’m going to leave my Roles questions for a future post and focus primarily on authentication at this point in time.

in my Blazor app, I have configured the following

builder.Services.AddOidcAuthentication(options =>
{
	builder.Configuration.Bind("Auth0", options.ProviderOptions);
	options.ProviderOptions.ResponseType = "code";
	options.ProviderOptions.DefaultScopes.Add("offline_access");
});

I have not configured any custom AuthenticationStateProvider as I’m not sure if it’s necessary or just muddying the waters.

In my API I have added

// Configure Services
services
	.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
	.AddJwtBearer(options =>
	{
		options.Authority =  $"https://{Configuration["Auth0:Authority"]}/";
		options.Audience = Configuration["Auth0:Audience"];
		// If the access token does not have a `sub` claim, `User.Identity.Name` will be `null`. Map it to a different claim by setting the NameClaimType below.
		options.TokenValidationParameters = new TokenValidationParameters
		{
			NameClaimType = ClaimTypes.NameIdentifier
		};
	});

services.AddCors(opts =>
{
	opts.AddDefaultPolicy(builder =>
	{
		builder
			.AllowAnyOrigin()
			.AllowAnyMethod()
			.AllowAnyHeader();
	});
});

// Configure
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();

When I launch my Blazor app, I am able to successfully authenticate and see the appropriate values on a page as follows

<AuthorizeView>
    <Authorized>
        You're logged in
    </Authorized>
    <NotAuthorized>
        You have yet to authenticate
    </NotAuthorized>
</AuthorizeView>

The trouble comes when I try and make an authenticated request to the server. I don’t know how to configure Blazor to pass my bearer token along with my api request. All of my requests result in a 401 response.

When I open the chrome developer tools after a sucessful authentication, I do see two entries in the “session storage”

oidc.user:[authority]:[clientId]
Microsoft.AspNetCore.Components.WebAssembly.Authentication.CachedAuthSettings

though I’m pretty sure I want these values in “local storage” and not simply session storage.

Hi @chase-cannect
if you want to attach token to your api calls add following class to your Blazor app

public class CustomAuthorizationMessageHandler : AuthorizationMessageHandler
{
    public CustomAuthorizationMessageHandler(
        IAccessTokenProvider provider,
        NavigationManager navigation)
        : base(provider, navigation)
    {
        var url = "https://YOUR_API_URL"; // <-- insert your value here
        ConfigureHandler(authorizedUrls: new[] { url });
    }
}

and use it in Program.cs like that

      builder.Services.AddHttpClient("ServerAPI", 
            client => client.BaseAddress = new Uri("YOUR_API_URL))
          .AddHttpMessageHandler<CustomAuthorizationMessageHandler>();