Dilemma with JWT Management in Blazor Server + Worker Service + Centralized WebAPI
Hello community!
I'm facing an architectural dilemma regarding JWT authentication management in a scenario where I have multiple types of clients and a single centralized WebAPI as the backend. I would really appreciate insights from anyone who has solved similar problems.
Context:
I have two main client applications:
The problem:
I want all applications to use JWT for authentication, without exposing the database directly to any client.
In Blazor Server, this has been especially challenging due to its circuit model and the lifecycle of DI services.
I tried creating an in-memory token store with a simple interface, like:
public interface ITokenProvider
{
string? GetToken();
void SetToken(string? token);
}
and an implementation that just keeps the token in a private variable.
However, I've found that Blazor Server creates new instances of my TokenProvider for each injection into components or DI services, even when registered as Scoped.
This causes the token to be lost when navigating or when a new circuit is created—different parts of the app see different instances (and thus, different token values).
If I switch to Singleton, all users share the same token, which is a security risk and not acceptable.
I can't find a clean way to share the token across all components and services in Blazor Server, without having to pass the token manually in every request.
I'm facing an architectural dilemma regarding JWT authentication management in a scenario where I have multiple types of clients and a single centralized WebAPI as the backend. I would really appreciate insights from anyone who has solved similar problems.
Context:
I have two main client applications:
- A Worker Service (background service, no UI), which will run on client machines as needed.
- A web application using Blazor Server.
- In the future, I also plan to add mobile apps.
The problem:
I want all applications to use JWT for authentication, without exposing the database directly to any client.
In Blazor Server, this has been especially challenging due to its circuit model and the lifecycle of DI services.
I tried creating an in-memory token store with a simple interface, like:
public interface ITokenProvider
{
string? GetToken();
void SetToken(string? token);
}
and an implementation that just keeps the token in a private variable.
However, I've found that Blazor Server creates new instances of my TokenProvider for each injection into components or DI services, even when registered as Scoped.
This causes the token to be lost when navigating or when a new circuit is created—different parts of the app see different instances (and thus, different token values).
If I switch to Singleton, all users share the same token, which is a security risk and not acceptable.
I can't find a clean way to share the token across all components and services in Blazor Server, without having to pass the token manually in every request.