Context:
About six months ago, I started a project using Blazor at my company. At that time, I knew very little about Blazor and had to learn as I developed the application. Previously, I worked with ASP.NET Framework 4.6.2, and this new project is part of our plan to eventually migrate our legacy system to a more modern framework.
The Problem:
There were several aspects of Blazor that kept me up at night because they were so different from ASP.NET. For example, the component lifecycle, circuits managed by SignalR, and one of the most challenging parts—working with cookies and authentication. Let me explain how authentication is currently implemented in my application.
Summary:
We have an external API separate from the Blazor project, which provides routes for login and token refresh. Initially, I implemented authentication by creating a controller in my Blazor application to handle the authentication cookies. After much research, I realized this was the only way to make it work because cookies must be attached to the HTTP response. Since Blazor doesn't always perform traditional HTTP requests, I had to force a page reload to ensure the cookie was attached. The controller was implemented as follows:
Step 1: I created an AuthenticationStateProvider to manage the authentication state. To do this, I needed to retrieve the token stored in the cookie. Since my application uses Blazor Server, I couldn’t rely on localStorageService or sessionStorageService for JavaScript-based storage. Instead, I had to rely on something that I believe became the root of my issues: I created a service to fetch data from the HttpContext. For this, I needed to use the HttpContextAccessor to access the cookies I had saved.
Step 2: I then created an HttpClientFactory and a DelegatingHandler to attach the token to all API calls automatically.
This approach worked fine for a while, but I started facing issues when implementing token refresh functionality. Here’s how I attempted to do it:In the DelegatingHandler, I checked whether the API response indicated an expired token. If so, I would call the refresh token API, retrieve the new token, update the token in the request object, and resend the request. However, the problem with this approach was updating the token in the cookie. Even after updating the cookie, the HttpContextAccessor would still reference the old HttpContext because no new HTTP request had been made to the Blazor server. This issue persisted unless I forced a page reload, which isn’t an ideal solution.
Possible Solution:One idea I had was to create a Blazor component to manage the cookie state. Using this approach, I could handle cookie updates via state changes rather than relying on the HttpContextAccessor for every request. The HttpContextAccessor would only be used for the initial retrieval of the cookie. After that, I would store the cookie in a service that lives throughout the circuit's lifecycle. Then, when the circuit refreshes (e.g., during another HTTP request), the updated cookie would sync with the HttpContext, and the property holding the cookie in the service would always remain accurate.However, this approach is still not entirely clear to me, and I’m unsure how to implement it properly.
If you have any advice on improving this implementation or a better way to handle authentication in Blazor Server, I’d greatly appreciate it.




