Avoiding AccessTokenNotAvailableException when using the Blazor WebAssembly Hosted template with individual user accounts
Tags: blazor, webdev, csharp, dotnet
Published: 2020-07-06 22:07:56

---
title: Avoiding AccessTokenNotAvailableException when using the Blazor WebAssembly Hosted template with individual user accounts
published: true
date: 2020-06-09 08:00:00 UTC
tags: Blazor,WebDev,CSharp,DotNet
canonical_url: https://chrissainty.com/avoiding-accesstokennotavailableexception-when-using-blazor-webassembly-hosted-template-with-individual-user-accounts/
---

 ![Avoiding AccessTokenNotAvailableException when using the Blazor WebAssembly Hosted template with individual user accounts](https://chrissainty.com/content/images/2020/06/AccessTokenNotAvailableException-1.jpg)

Blazor WebAssembly has shipped with a host of new options for authentication. We now have the ability to create Blazor Wasm apps which can authenticate against Active Directory, Azure AD, Azure AD B2C, Identity Server, in fact any OIDC provider should work with Blazor. But, there is a little gotcha which has tripped a few people up when building applications which mix protected and unprotected endpoints using the Blazor WebAssembly ASP.NET Core Hosted template with Individual user accounts enabled.

The default configuration in the template uses an HTTP client with a custom message handler called `BaseAddressAuthorizationMessageHandler`. This handler attempts to attach an access token to any outgoing requests and if it can't find one, it throws an exception.

This makes sense if you're only calling protected endpoints, but if your application allows the user to call **unprotected endpoints without logging in** then you might see a `AccessTokenNotAvailableException` in the browser console.

![Avoiding AccessTokenNotAvailableException when using the Blazor WebAssembly Hosted template with individual user accounts](https://chrissainty.com/content/images/2020/06/AccessTokenNotAvailableException.jpg)

In this post, I'm going to show you how to configure an additional `HttpClient` instance which can be used by unauthenticated users to call unprotected endpoints, avoiding an `AccessTokenNotAvailableException`.

## Default Configuration

When you create a new Blazor WebAssembly application using ASP.NET Core Identity, you'll find the following configuration in the `Program.Main` method.

<!--kg-card-begin: markdown-->
```
builder.Services.AddHttpClient("BlazorApp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
                .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

```
<!--kg-card-end: markdown-->

This sets up the `HttpClient` for the application using a custom handler, `BaseAddressAuthorizationMessageHandler`. This handler is really useful as it saves us having to worry about adding access tokens to our API requests manually. However, as I explained in the introduction, this is also a potential issue.

If we delve into the source code, we can see that the `BaseAddressAuthorizationMessageHandler` inherits from another class called `AuthorizationMessageHandler`, this is the class where we find the potential gotcha.

<!--kg-card-begin: markdown-->
```
var tokenResult = _tokenOptions != null ?
                        await _provider.RequestAccessToken(_tokenOptions) :
                        await _provider.RequestAccessToken();
                        
if (tokenResult.TryGetToken(out var token))
{
    _lastToken = token;
    _cachedHeader = new AuthenticationHeaderValue("Bearer", _lastToken.Value);
}
else
{
    throw new AccessTokenNotAvailableException(_navigation, tokenResult, _tokenOptions?.Scopes);
}

```
<!--kg-card-end: markdown-->

The piece of code above is looking for a token so it can add it to the authentication header of the outgoing request. And as you can see, if one isn't found then an exception is thrown, `AccessTokenNotAvailableExcpetion`.

The default template configuration actually gives us a hint of this potential issue on the `FetchData` component.

<!--kg-card-begin: markdown-->
```
protected override async Task OnInitializedAsync()
{
    try
    {
        forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
    }
    catch (AccessTokenNotAvailableException exception)
    {
        exception.Redirect();
    }
}

```
<!--kg-card-end: markdown-->

There is a `try..catch` setup to specifically check for this exception and redirect the user to login.

Now we can see where the problem comes from, what's the solution?

## Configuring a second HttpClient for unauthenticated requests

The answer is to add a second HTTP Client instance which doesn't use this message handler. We can then use this instance when we want to make unprotected requests, and use the original one for everything else.

The easiest way we can achieve this is by adding the following line to our `Program.Main`.

<!--kg-card-begin: markdown-->
```
builder.Services.AddHttpClient("BlazorApp.PublicServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

```
<!--kg-card-end: markdown-->

This will add another named HTTP Client instance to our application but, as you can see, there is no special message handler added this time.

Once this is done, we can get an instance of this client by injecting `IHttpClientFactory` into our component or service and using the `Create` method with the name of the client.

<!--kg-card-begin: markdown-->
```
@inject IHttpClientFactory HttpClientFactory

...

@code {
    private async Task GetSomethingFromAPI()
    {
        var client = HttpClientFactory.Create("BlazorApp.PublicServerAPI");
        var result = client.GetFromJsonAsync<Something>("/api/something");
    }
}

```
<!--kg-card-end: markdown-->

Another option, which in my opinion is a bit nicer as I'm not a fan of magic strings, is to create a _typed client_. This means we can request an instance by type rather than use the magic string solution.

To do this we first need to add a new class, we'll call it `PublicClient` and add the following code.

<!--kg-card-begin: markdown-->
```
public class PublicClient
{
    public HttpClient Client { get; }
    
    public PublicClient(HttpClient httpClient)
    {
        Client = httpClient;
    }
}

```
<!--kg-card-end: markdown-->

This code is quite straightforward, we're just accepting a instance of `HttpClient` through DI and saving it off to the `Client` property.

Then in `Program.Main` we add the following code.

<!--kg-card-begin: markdown-->
```
builder.Services.AddHttpClient<PublicClient>(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

```
<!--kg-card-end: markdown-->

This is going to inject an `HttpClient` instance, configured with the base address we've specified, into our `PublicClient` class. It will also add our `PublicClient` class into the DI container so we can request an instance of it with the preconfigured `HttpClient`.

We can then use it like this.

<!--kg-card-begin: markdown-->
```
@inject PublicClient PublicClient

...

@code {
    private async Task GetSomethingFromAPI()
    {
        var result = PublicClient.Client.GetFromJsonAsync<Something>("/api/something");
    }
}

```
<!--kg-card-end: markdown-->

I think this is a much cleaner way to do things, it's saved us a line of code in our component and it's more obvious at a glance the type of client we are using. Using this approach also allows us to abstract the underlying `HttpClient` entirely, if we wish. We can write methods on the `PublicClient` so we never expose the `HttpClient` to calling code.

<!--kg-card-begin: markdown-->
```
public class PublicClient
{
    private HttpClient _client
    
    public PublicClient(HttpClient httpClient)
    {
        _client = httpClient;
    }
    
    public async Task<SomeThing> GetSomething()
    {
        var result = await _client.GetFromJsonAsync<SomeThing>("/api/something");
        return result;
    }
}

```
<!--kg-card-end: markdown--><!--kg-card-begin: markdown-->
```
@inject PublicClient PublicClient

...

@code {
    private async Task GetSomethingFromAPI()
    {
        var result = PublicClient.GetSomething();
    }
}

```
<!--kg-card-end: markdown-->

This code is now really succinct, we've also centralised all our API calling code which should make any future maintenance simpler.

## Summary

In this post we've explored a potential issue with unauthenticated users calling unprotected endpoints using the default `HttpClient` that comes with the Blazor WebAssembly auth templates. We've investigated Blazors source to understand where this comes from and then we've applied a solution which was to add a second `HttpClient` instance.

Once we had this working we also looked at a different implementation of the solution which made our code a bit simpler and easier to understand, as well as potentially making API calling code easier to maintain in the long run.