Authentication and AuthorizeView
AuthenticationStateProvider is an abstract class whose GetAuthenticationStateAsync() method returns a Task<AuthenticationState> wrapping a ClaimsPrincipal representing the current user, authenticated or anonymous. Blazor cascades this state through the component tree (via CascadingAuthenticationState in earlier versions, or built into the app template in .NET 8+), which is what lets any descendant component, including AuthorizeView, query the user's identity without each one re-fetching it independently.
Cricket analogy: Like an official scorer whose confirmed scorecard is broadcast to every screen in the stadium simultaneously, AuthenticationStateProvider's GetAuthenticationStateAsync produces one ClaimsPrincipal that cascades down to every component in the app.
AuthorizeView Component
AuthorizeView is a component that conditionally renders one of three named RenderFragments based on the cascaded authentication state: Authorized content shows once the user is confirmed to meet the requirements, NotAuthorized content shows if they don't, and Authorizing content shows briefly while the check is still in progress (relevant for providers that resolve asynchronously). Inside the Authorized fragment, a context variable exposes the current ClaimsPrincipal, letting you read claims like context.User.Identity?.Name directly in markup.
Cricket analogy: Like a stadium screen showing a player's name only once their identity is confirmed, showing a 'verifying' message during a review, and showing nothing if unconfirmed, AuthorizeView's Authorized, Authorizing, and NotAuthorized templates render different content for each of those three states.
Beyond a simple authenticated/anonymous check, AuthorizeView accepts a Roles parameter for a comma-separated role list, restricting the Authorized content to users in at least one of those roles, and a Policy parameter that references a named authorization policy registered in your services (via AddAuthorization) for arbitrarily complex custom logic that role membership alone can't express.
Cricket analogy: Like only allowing the designated wicketkeeper to stand behind the stumps regardless of who else is on the field, AuthorizeView Roles="Captain" only renders its Authorized content for users in that specific role, while Policy checks a more nuanced rule like minimum experience.
The [Authorize] Attribute and CascadingAuthenticationState
Applying [Authorize] (optionally with Roles or Policy) directly to a routable component is enforced at the routing layer by AuthorizeRouteView, which the app's Routes.razor or App.razor renders instead of a plain RouteView; it checks the cascaded authentication state before the component ever executes its lifecycle methods, and renders configurable NotAuthorized or NotFound content templates when the check fails, rather than letting the protected component itself leak any content.
Cricket analogy: Like a stadium gate that automatically checks a ticket before letting a fan reach a premium seating section, the [Authorize] attribute on a routable component is enforced by the Router's AuthorizeRouteView before rendering, showing a NotAuthorized template like a gate attendant redirecting an invalid ticket holder.
@page "/admin/reports"
@attribute [Authorize(Roles = "Admin,Auditor")]
<h3>Internal Reports</h3>
<AuthorizeView Roles="Admin">
<Authorized>
<p>Welcome, @context.User.Identity?.Name. You can edit and export reports.</p>
</Authorized>
<NotAuthorized>
<p>You have read-only access to reports.</p>
</NotAuthorized>
</AuthorizeView>In a Blazor WebAssembly app, [Authorize] and AuthorizeView only control what the client-side UI shows; they run entirely in the browser and can, in principle, be bypassed by a modified client. Every API your Blazor app calls must independently authorize each request server-side, typically via [Authorize] on ASP.NET Core controllers or minimal API endpoints, since client-side checks are UX, not a security boundary.
Custom AuthenticationStateProvider
For token-based auth (a common pattern in Blazor WebAssembly), you implement a custom class deriving from AuthenticationStateProvider that overrides GetAuthenticationStateAsync to read a stored JWT (commonly from browser local storage via JS interop), parse its claims, and construct the ClaimsPrincipal. After a login or logout action changes that stored token, you must explicitly call the base class's NotifyAuthenticationStateChanged(Task<AuthenticationState>) method to push the update, since nothing else will automatically detect that the underlying credential changed.
Cricket analogy: Like a scorer who must actively announce an overturned decision over the PA system or the crowd keeps cheering for the wrong outcome, a custom AuthenticationStateProvider must call NotifyAuthenticationStateChanged after login so every AuthorizeView actually re-renders with the new ClaimsPrincipal.
Forgetting to call NotifyAuthenticationStateChanged after a login or logout action inside a custom AuthenticationStateProvider leaves every AuthorizeView and [Authorize]-protected route rendering stale state (still showing the anonymous view, for example) until the user performs a full page reload, which happens to reset AuthenticationStateProvider's cached Task. This is one of the most common bugs in custom Blazor WebAssembly authentication implementations.
- AuthenticationStateProvider.GetAuthenticationStateAsync produces a ClaimsPrincipal that cascades to every component in the app.
- AuthorizeView renders Authorized, NotAuthorized, or Authorizing content based on the cascaded authentication state.
- AuthorizeView's Roles and Policy parameters restrict Authorized content to specific roles or a named authorization policy.
- [Authorize] on a routable component is enforced by AuthorizeRouteView at the routing layer before the component renders.
- Client-side authorization checks in Blazor WebAssembly are UX only; the server must independently authorize every API request.
- A custom AuthenticationStateProvider typically reads a stored token (e.g. a JWT) to build the ClaimsPrincipal.
- NotifyAuthenticationStateChanged must be called explicitly after login/logout, or the UI keeps showing stale authentication state.
Practice what you learned
1. What does AuthenticationStateProvider.GetAuthenticationStateAsync return?
2. Which AuthorizeView render fragment shows content while the authentication check is still resolving?
3. What enforces the [Authorize] attribute on a routable Blazor component?
4. Why must a custom AuthenticationStateProvider call NotifyAuthenticationStateChanged after login?
5. Why can't client-side [Authorize] checks in Blazor WebAssembly be relied on as a security boundary?
Was this page helpful?
You May Also Like
Forms and EditForm
Learn how Blazor's EditForm component, EditContext, and built-in input components work together to build validated forms.
Navigation and NavigationManager
Understand how Blazor's NavigationManager service enables programmatic navigation, URL inspection, and location-change event handling.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics