A free and open-source web framework that enables developers to create web apps using C# and HTML, developed by Microsoft.
Hello @Bob N ,
Thank you for sharing.
I can see why this feels confusing. The immediate problem is not JWT itself; it is the dependency injection setup.
AddHttpMessageHandler<SecureHttpDelegateHandler>() tells IHttpClientFactory to create that handler through dependency injection. That means every constructor dependency of SecureHttpDelegateHandler must be registered in the service container.
In your failing version, the handler requires AuthService:
public SecureHttpDelegateHandler(TokenStorage tokenStorage, AuthService auth)
{
_tokenStorage = tokenStorage;
_auth = auth;
}
However, AuthService is not registered in the code shown, which matches the exception you posted.
For this setup, the registrations should look more like this:
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped<TokenStorage>();
builder.Services.AddScoped<AuthService>();
builder.Services.AddScoped<AuthenticationStateProvider, AppAuthenticationStateProvider>();
builder.Services.AddScoped<PostService>();
builder.Services.AddTransient<SecureHttpDelegateHandler>();
builder.Services.AddHttpClient("XXXAPI", client =>
{
client.BaseAddress = new Uri("https://jsonplaceholder.typicode.com");
})
.AddHttpMessageHandler<SecureHttpDelegateHandler>();
builder.Services.AddScoped(sp =>
sp.GetRequiredService<IHttpClientFactory>().CreateClient("XXXAPI"));
builder.Services.AddAuthorizationCore();
var app = builder.Build();
await app.RunAsync();
There are two specific issues in your sample:
-
AuthServiceneeds to be registered so the handler can be constructed. -
CreateClient("XXXPI")does not match the registered client name, which is"XXXAPI". The names must match exactly.
Microsoft's IHttpClientFactory guidance explains that delegating handlers are used as outgoing request middleware, and the Blazor WebAssembly security guidance shows the recommended pattern of registering an authorization handler and attaching it with AddHttpClient(...).AddHttpMessageHandler(...):
If you are using the built-in Blazor/OIDC authentication flow, I would also consider using AuthorizationMessageHandler or BaseAddressAuthorizationMessageHandler, because that is the framework-supported pattern for attaching access tokens to outgoing requests:
I hope this helps. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guidance or provide feedback.
Thank you.