This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
This article describes ASP.NET Core's support for the configuration and management of security in Blazor apps.
Blazor uses the existing ASP.NET Core authentication mechanisms to establish the user's identity. The exact mechanism depends on how the Blazor app is hosted, server-side or client-side.
Security scenarios differ between authorization code running server-side and client-side in Blazor apps. For authorization code that runs on the server, authorization checks are able to enforce access rules for areas of the app and components. Because client-side code execution can be tampered with, authorization code executing on the client can't be trusted to absolutely enforce access rules or control the display of client-side content.
If authorization rule enforcement must be guaranteed, don't implement authorization checks in client-side code. Build a Blazor Web App that only relies on server-side rendering (SSR) for authorization checks and rule enforcement.
If authorization rule enforcement and the security of data and code must be guaranteed, don't develop a client-side app. Build a Blazor Server app.
ASP.NET Core Identity is designed to work in the context of HTTP request and response communication, which generally isn't the Blazor app client-server communication model. ASP.NET Core apps that use ASP.NET Core Identity for user management should use Razor Pages instead of Razor components for Identity-related UI, such as user registration, login, logout, and other user management tasks. Building Razor components that directly handle Identity tasks is possible for several scenarios but isn't recommended or supported by Microsoft.
Don't store app secrets, connection strings, credentials, passwords, personal identification numbers (PINs), private .NET/C# code, or private keys/tokens in client-side code, which is always insecure. Client-side Blazor code should access secure services and databases through a secure web API that you control.
In test/staging and production environments, server-side Blazor code and web APIs should use secure authentication flows that avoid maintaining credentials within project code or configuration files. Outside of local development testing, we recommend avoiding the use of environment variables to store sensitive data, as environment variables aren't the most secure approach. For local development testing, the Secret Manager tool is recommended for securing sensitive data. For more information, see the following resources:
For client-side and server-side local development and testing, use the Secret Manager tool to secure sensitive credentials.
Managed identities for Microsoft Azure services
For Microsoft Azure services, we recommend using managed identities. Managed identities securely authenticate to Azure services without storing credentials in app code. For more information, see the following resources:
Blazor stores request tokens in component state, which guarantees that antiforgery tokens are available to interactive components, even when they don't have access to the request.
Note
Antiforgery mitigation is only required when submitting form data to the server encoded as application/x-www-form-urlencoded, multipart/form-data, or text/plain since these are the only valid form enctypes.
For more information, see the following resources:
Server-side Blazor apps are configured for security in the same manner as ASP.NET Core apps. For more information, see the articles under ASP.NET Core security topics.
The authentication context is only established when the app starts, which is when the app first connects to the WebSocket over a SignalR connection with the client. Authentication can be based on a cookie or some other bearer token, but authentication is managed via the SignalR hub and entirely within the circuit. The authentication context is maintained for the lifetime of the circuit. Apps periodically revalidate the user's authentication state every 30 minutes.
Blazor differs from a traditional server-rendered web apps that make new HTTP requests with cookies on every page navigation. Authentication is checked during navigation events. However, cookies aren't involved. Cookies are only sent when making an HTTP request to a server, which isn't what happens when the user navigates in a Blazor app. During navigation, the user's authentication state is checked within the Blazor circuit, which you can update at any time on the server using the RevalidatingAuthenticationStateProvider abstraction.
Important
Implementing a custom NavigationManager to achieve authentication validation during navigation isn't recommended. If the app must execute custom authentication state logic during navigation, use a custom AuthenticationStateProvider.
The built-in or custom AuthenticationStateProvider service obtains authentication state data from ASP.NET Core's HttpContext.User. This is how authentication state integrates with existing ASP.NET Core authentication mechanisms.
Server-side Blazor apps live in server memory, and multiple app sessions are hosted within the same process. For each app session, Blazor starts a circuit with its own dependency injection container scope, thus scoped services are unique per Blazor session.
Warning
We don't recommend apps on the same server share state using singleton services unless extreme care is taken, as this can introduce security vulnerabilities, such as leaking user state across circuits.
You can use stateful singleton services in Blazor apps if they're specifically designed for it. For example, use of a singleton memory cache is acceptable because a memory cache requires a key to access a given entry. Assuming users don't have control over the cache keys that are used with the cache, state stored in the cache doesn't leak across circuits.
Server-side security of sensitive data and credentials
In test/staging and production environments, server-side Blazor code and web APIs should use secure authentication flows that avoid maintaining credentials within project code or configuration files. Outside of local development testing, we recommend avoiding the use of environment variables to store sensitive data, as environment variables aren't the most secure approach. For local development testing, the Secret Manager tool is recommended for securing sensitive data. For more information, see the following resources:
When issuing the .NET CLI command to create and configure the server-side Blazor app, indicate the authentication mechanism with the -au|--auth option:
Organizational authentication for multiple tenants
Windows
Windows Authentication
For more information, see the dotnet new command in the .NET Core Guide.
When issuing the .NET CLI command to create and configure the server-side Blazor app, indicate the authentication mechanism with the -au|--auth option:
Organizational authentication for multiple tenants
Windows
Windows Authentication
For more information:
See the dotnet new command in the .NET Core Guide.
Execute the help command for the template in a command shell:
dotnet new {PROJECT TEMPLATE} --help
In the preceding command, the {PROJECT TEMPLATE} placeholder is the project template.
Blazor Identity UI (Individual Accounts)
Blazor supports generating a full Blazor-based Identity UI when you choose the authentication option for Individual Accounts.
The Blazor Web App template scaffolds Identity code for a SQL Server database. The command line version uses SQLite and includes a SQLite database for Identity.
The template:
Supports interactive server-side rendering (interactive SSR) and client-side rendering (CSR) scenarios with authenticated users.
Adds Identity Razor components and related logic for routine authentication tasks, such as signing users in and out. The Identity components also support advanced Identity features, such as account confirmation and password recovery and multifactor authentication using a third-party app. Note that the Identity components themselves don't support interactivity.
Adds the Identity-related packages and dependencies.
References the Identity packages in _Imports.razor.
Creates a custom user Identity class (ApplicationUser).
Creates and registers an EF Core database context (ApplicationDbContext).
Configures routing for the built-in Identity endpoints.
When you choose the Interactive WebAssembly or Interactive Auto render modes, the server handles all authentication and authorization requests, and the Identity components render statically on the server in the Blazor Web App's main project.
The framework provides a custom AuthenticationStateProvider in both the server and client (.Client) projects to flow the user's authentication state to the browser. The server project calls AddAuthenticationStateSerialization, while the client project calls AddAuthenticationStateDeserialization. Authenticating on the server rather than the client allows the app to access authentication state during prerendering and before the .NET WebAssembly runtime is initialized. The custom AuthenticationStateProvider implementations use the Persistent Component State service (PersistentComponentState) to serialize the authentication state into HTML comments and then read it back from WebAssembly to create a new AuthenticationState instance. For more information, see the Manage authentication state in Blazor Web Apps section.
When you choose the Interactive WebAssembly or Interactive Auto render modes, the server handles all authentication and authorization requests, and the Identity components render statically on the server in the Blazor Web App's main project. The project template includes a PersistentAuthenticationStateProvider class (reference source) in the .Client project to synchronize the user's authentication state between the server and the browser. The class is a custom implementation of AuthenticationStateProvider. The provider uses the Persistent Component State service (PersistentComponentState) to prerender the authentication state and persist it to the page.
Blazor Identity depends on DbContext instances not created by a factory, which is intentional because DbContext is sufficient for the project template's Identity components to render statically without supporting interactivity.
For a description on how global interactive render modes are applied to non-Identity components while at the same time enforcing static SSR for the Identity components, see ASP.NET Core Blazor render modes.
Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).
Manage authentication state in Blazor Web Apps
This section applies to Blazor Web Apps that adopt:
A client-side authentication state provider is only used within Blazor and isn't integrated with the ASP.NET Core authentication system. During prerendering, Blazor respects the metadata defined on the page and uses the ASP.NET Core authentication system to determine if the user is authenticated. When a user navigates from one page to another, a client-side authentication provider is used. When the user refreshes the page (full-page reload), the client-side authentication state provider isn't involved in the authentication decision on the server. Since the user's state isn't persisted by the server, any authentication state maintained client-side is lost.
To address this, the best approach is to perform authentication within the ASP.NET Core authentication system. The client-side authentication state provider only takes care of reflecting the user's authentication state. Examples for how to accomplish this with authentication state providers are demonstrated by the Blazor Web App project template and described below.
The API only serializes the server-side name and role claims for access in the browser. To include all claims, set SerializeAllClaims to true in the server-side call to AddAuthenticationStateSerialization:
PersistentAuthenticationStateProvider (reference source): For Blazor Web Apps that adopt CSR. This is a client-side AuthenticationStateProvider that determines the user's authentication state by looking for data persisted in the page when it was rendered on the server. This authentication state is fixed for the lifetime of CSR. If the user needs to log in or out, a full-page reload is required. This only provides a user name and email for display purposes. It doesn't include tokens that authenticate to the server when making subsequent requests, which is handled separately using a cookie that's included on HttpClient requests to the server.
Note
Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).
public class ExampleService
{
public async Task<string> ExampleMethod(AuthenticationStateProvider authStateProvider)
{
var authState = await authStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
return $"{user.Identity.Name} is authenticated.";
}
else
{
return "The user is NOT authenticated.";
}
}
}
Register the service as scoped. In a server-side Blazor app, scoped services have a lifetime equal to the duration of the client connection circuit.
In the Program file:
builder.Services.AddScoped<ExampleService>();
In Startup.ConfigureServices of Startup.cs:
services.AddScoped<ExampleService>();
In the following InjectAuthStateProvider component:
ExampleService is resolved with OwningComponentBase.ScopedServices and GetRequiredService, which returns the correct, initialized instance of ExampleService that exists for the lifetime of the user's circuit.
Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).
Disable prerendering: Indicate the render mode with the prerender parameter set to false at the highest-level component in the app's component hierarchy that isn't a root component.
Note
Making a root component interactive, such as the App component, isn't supported. Therefore, prerendering can't be disabled directly by the App component.
For apps based on the Blazor Web App project template, prerendering is typically disabled where the Routes component is used in the App component (Components/App.razor) :
Authenticate the user on the server before the app starts: To adopt this approach, the app must respond to a user's initial request with the Identity-based sign-in page or view and prevent any requests to Blazor endpoints until they're authenticated. For more information, see Create an ASP.NET Core app with user data protected by authorization. After authentication, unauthorized content in prerendered Razor components is only shown when the user is truly unauthorized to view the content.
User state management
In spite of the word "state" in the name, AuthenticationStateProvider isn't for storing general user state. AuthenticationStateProvider only indicates the user's authentication state to the app, whether they are signed into the app and who they are signed in as.
Authentication uses the same ASP.NET Core Identity authentication as Razor Pages and MVC apps. The user state stored for ASP.NET Core Identity flows to Blazor without adding additional code to the app. Follow the guidance in the ASP.NET Core Identity articles and tutorials for the Identity features to take effect in the Blazor parts of the app.
Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).
Authentication state management at sign out
Server-side Blazor persists user authentication state for the lifetime of the circuit, including across browser tabs. To proactively sign off a user across browser tabs when the user signs out on one tab, you must implement a RevalidatingServerAuthenticationStateProvider (reference source) with a short RevalidationInterval.
Note
Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).
Temporary redirection URL validity duration
This section applies to Blazor Web Apps.
Use the RazorComponentsServiceOptions.TemporaryRedirectionUrlValidityDuration option to get or set the lifetime of ASP.NET Core Data Protection validity for temporary redirection URLs emitted by Blazor server-side rendering. These are only used transiently, so the lifetime only needs to be long enough for a client to receive the URL and begin navigation to it. However, it should also be long enough to allow for clock skew across servers. The default value is five minutes.
In the following example the value is extended to seven minutes:
In client-side Blazor apps, client-side authentication checks can be bypassed because all client-side code can be modified by users. The same is true for all client-side app technologies, including JavaScript SPA frameworks and native apps for any operating system.
Secure data in Blazor Web Apps with Interactive Auto rendering
When a Blazor Web App adopts server-side rendering (SSR) and client-side rendering (CSR) for components or an entire app that specifies the Interactive Auto render mode, authorization to access components and data is applied in two places. The component restricts access to itself (and any data that it obtains) when rendered on the server by virtue of an authorization attribute in the component's definition file (@attribute [Authorize]). When the component is rendered on the client, access to data is restricted via the server web API endpoints that are called from the client. Care must be taken when securing data access in both locations to prevent improper data access.
Consider the following scenario where secure weather data is displayed by a component. The following example can be examined and demonstrated in a running sample app with either the BlazorWebAppEntra/BlazorWebAppEntraBff samples (.NET 9 or later) or the BlazorWebAppOidc sample (.NET 8 or later) in the Blazor samples GitHub repository (dotnet/blazor-samples) (how to download).
The client project maintains a WeatherForecast class to hold weather data:
public sealed class WeatherForecast(DateOnly date, int temperatureC, string summary)
{
public DateOnly Date { get; set; } = date;
public int TemperatureC { get; set; } = temperatureC;
public string? Summary { get; set; } = summary;
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
The client project's IWeatherForecaster interface defines a GetWeatherForecastAsync method for obtaining weather data:
public interface IWeatherForecaster
{
Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync();
}
The client project's ClientWeatherForecaster service implements IWeatherForecaster. The GetWeatherForecastAsync method calls a web API in the server project at the /weather-forecast endpoint for weather data:
internal sealed class ClientWeatherForecaster(HttpClient httpClient)
: IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync() =>
await httpClient.GetFromJsonAsync<WeatherForecast[]>("/weather-forecast") ??
throw new IOException("No weather forecast!");
}
The client project maintains a Weather component that:
The server project implements IWeatherForecaster as ServerWeatherForecaster, which generates and returns mock weather data via its GetWeatherForecastAsync method:
public class ServerWeatherForecaster() : IWeatherForecaster
{
public readonly string[] summaries =
[
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot",
"Sweltering", "Scorching"
];
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
// Simulate asynchronous loading to demonstrate streaming rendering
await Task.Delay(500);
return Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
}
}
The server project maintains a secure web API endpoint for client weather data calls:
Using the preceding approach, there are two systems in place to supply secure weather data to the user:
When the Weather component is rendered on the server, the ServerWeatherForecaster service's GetWeatherForecastAsync method is used directly to obtain the weather data. The security of the data is enforced by the component's [Authorize] attribute. In summary, the security of the weather data is enforced by the component.
When the Weather component is rendered on the client, the ClientWeatherForecaster service is used to make a web API call to the secure /weather-forecast endpoint that applies the RequireAuthorization extension method. If the user has the authority to access weather data, the endpoint uses the ServerWeatherForecaster service to call GetWeatherForecastAsync. The data is returned to the client. In summary, the security of the weather data is enforced by the server app's web API endpoint.
The preceding approach works well when the security requirements of the web API match the security requirements of the component. For example, the same authorization policy can be applied to both the web API endpoint and the component.
Complex scenarios require additional planning and implementation. For example, a server web API that has multiple callers with different access permissions either requires a more sophisticated authorization policy, one or more additional policies, or additional endpoints with different access requirements.
As you build security into apps that adopt Interactive Auto rendering, be mindful that the security implemented for the server's web API endpoints doesn't secure the server's service implementation that's used when a component is rendered on the server and accesses data through the service. Carefully weigh the difference between accessing data on the server during SSR versus accessing the data on a client web API request during CSR. Strategically apply security to avoid improper access to data.
AuthenticationStateProvider is the underlying service used by the AuthorizeView component and cascading authentication services to obtain the authentication state for a user.
Expose the authentication state as a cascading parameter
If authentication state data is required for procedural logic, such as when performing an action triggered by the user, obtain the authentication state data by defining a cascading parameter of type Task<AuthenticationState>, as the following example demonstrates.
CascadeAuthState.razor:
@page "/cascade-auth-state"
<h1>Cascade Auth State</h1>
<p>@authMessage</p>
@code {
private string authMessage = "The user is NOT authenticated.";
[CascadingParameter]
private Task<AuthenticationState>? authenticationState { get; set; }
protected override async Task OnInitializedAsync()
{
if (authenticationState is not null)
{
var authState = await authenticationState;
var user = authState?.User;
if (user?.Identity is not null && user.Identity.IsAuthenticated)
{
authMessage = $"{user.Identity.Name} is authenticated.";
}
}
}
}
@page "/cascade-auth-state"
<h1>Cascade Auth State</h1>
<p>@authMessage</p>
@code {
private string authMessage = "The user is NOT authenticated.";
[CascadingParameter]
private Task<AuthenticationState>? authenticationState { get; set; }
protected override async Task OnInitializedAsync()
{
if (authenticationState is not null)
{
var authState = await authenticationState;
var user = authState?.User;
if (user?.Identity is not null && user.Identity.IsAuthenticated)
{
authMessage = $"{user.Identity.Name} is authenticated.";
}
}
}
}
If user.Identity.IsAuthenticated is true, claims can be enumerated and membership in roles evaluated.
With the release of ASP.NET Core 5.0.1 and for any additional 5.x releases, the Router component includes the PreferExactMatches parameter set to @true. For more information, see Migrate from ASP.NET Core 3.1 to 5.0.
In a client-side Blazor app, add authorization services to the Program file:
builder.Services.AddAuthorizationCore();
In a client-side Blazor app, add options and authorization services to the Program file:
In a server-side Blazor app, services for options and authorization are already present, so no further steps are required.
Authorization
After a user is authenticated, authorization rules are applied to control what the user can do.
Access is typically granted or denied based on whether:
A user is authenticated (signed in).
A user is in a role.
A user has a claim.
A policy is satisfied.
Each of these concepts is the same as in an ASP.NET Core MVC or Razor Pages app. For more information on ASP.NET Core security, see the articles under ASP.NET Core Security and Identity.
AuthorizeView component
The AuthorizeView component selectively displays UI content depending on whether the user is authorized. This approach is useful when you only need to display data for the user and don't need to use the user's identity in procedural logic.
The component exposes a context variable of type AuthenticationState (@context in Razor syntax), which you can use to access information about the signed-in user:
Although the AuthorizeView component controls the visibility of elements based on the user’s authorization status, it doesn't enforce security on the event handler itself. In the preceding example, the HandleClick method is only associated with a button visible to authorized users, but nothing prevents invoking this method from other places. To ensure method-level security, implement additional authorization logic within the handler itself or in the relevant API.
Razor components of Blazor Web Apps never display <NotAuthorized> content when authorization fails server-side during static server-side rendering (static SSR). The server-side ASP.NET Core pipeline processes authorization on the server. Use server-side techniques to handle unauthorized requests. For more information, see ASP.NET Core Blazor render modes.
Warning
Client-side markup and methods associated with an AuthorizeView are only protected from view and execution in the rendered UI in client-side Blazor apps. In order to protect authorized content and secure methods in client-side Blazor, the content is usually supplied by a secure, authorized web API call to a server API and never stored in the app. For more information, see Call a web API from an ASP.NET Core Blazor app and ASP.NET Core Blazor WebAssembly additional security scenarios.
The content of Authorized and NotAuthorized can include arbitrary items, such as other interactive components.
Authorization conditions, such as roles or policies that control UI options or access, are covered in the Authorization section.
If authorization conditions aren't specified, AuthorizeView uses a default policy:
Authenticated (signed-in) users are authorized.
Unauthenticated (signed-out) users are unauthorized.
The AuthorizeView component can be used in the NavMenu component (Shared/NavMenu.razor) to display a NavLink component (NavLink), but note that this approach only removes the list item from the rendered output. It doesn't prevent the user from navigating to the component. Implement authorization separately in the destination component.
Role-based and policy-based authorization
The AuthorizeView component supports role-based or policy-based authorization.
For role-based authorization, use the Roles parameter. In the following example, the user must have a role claim for either the Admin or Superuser roles:
<AuthorizeView Roles="Admin, Superuser">
<p>You have an 'Admin' or 'Superuser' role claim.</p>
</AuthorizeView>
To require a user have both Admin and Superuser role claims, nest AuthorizeView components:
<AuthorizeView Roles="Admin">
<p>User: @context.User</p>
<p>You have the 'Admin' role claim.</p>
<AuthorizeView Roles="Superuser" Context="innerContext">
<p>User: @innerContext.User</p>
<p>You have both 'Admin' and 'Superuser' role claims.</p>
</AuthorizeView>
</AuthorizeView>
The preceding code establishes a Context for the inner AuthorizeView component to prevent an AuthenticationState context collision. The AuthenticationState context is accessed in the outer AuthorizeView with the standard approach for accessing the context (@context.User). The context is accessed in the inner AuthorizeView with the named innerContext context (@innerContext.User).
For policy-based authorization, use the Policy parameter with a single policy name:
<AuthorizeView Policy="Over21">
<p>You satisfy the 'Over21' policy.</p>
</AuthorizeView>
To handle the case where the user should satisfy one of several policies, create a policy that confirms that the user satisfies other policies.
To handle the case where the user must satisfy several policies simultaneously, take either of the following approaches:
Create a policy for AuthorizeView that confirms that the user satisfies several other policies.
Nest the policies in multiple AuthorizeView components:
<AuthorizeView Policy="Over21">
<AuthorizeView Policy="LivesInCalifornia">
<p>You satisfy the 'Over21' and 'LivesInCalifornia' policies.</p>
</AuthorizeView>
</AuthorizeView>
Claims-based authorization is a special case of policy-based authorization. For example, you can define a policy that requires users to have a certain claim. For more information, see Policy-based authorization in ASP.NET Core.
Unauthenticated (signed-out) users are unauthorized.
Because .NET string comparisons are case-sensitive, matching role and policy names is also case-sensitive. For example, Admin (uppercase A) is not treated as the same role as admin (lowercase a).
Pascal case is typically used for role and policy names (for example, BillingAdministrator), but the use of Pascal case isn't a strict requirement. Different casing schemes, such as camel case, kebab case, and snake case, are permitted. Using spaces in role and policy names is unusual but permitted by the framework. For example, billing administrator is an unusual role or policy name format in .NET apps, but it's a valid role or policy name.
Content displayed during asynchronous authentication
Blazor allows for authentication state to be determined asynchronously. The primary scenario for this approach is in client-side Blazor apps that make a request to an external endpoint for authentication.
While authentication is in progress, AuthorizeView displays no content. To display content while authentication occurs, assign content to the Authorizing parameter:
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
</Authorized>
<Authorizing>
<p>You can only see this content while authentication is in progress.</p>
</Authorizing>
</AuthorizeView>
This approach isn't normally applicable to server-side Blazor apps. Server-side Blazor apps know the authentication state as soon as the state is established. Authorizing content can be provided in an app's AuthorizeView component, but the content is never displayed.
@page "/"
@attribute [Authorize]
You can only see this if you're signed in.
Important
Only use [Authorize] on @page components reached via the Blazor router. Authorization is only performed as an aspect of routing and not for child components rendered within a page. To authorize the display of specific parts within a page, use AuthorizeView instead.
The [Authorize] attribute also supports role-based or policy-based authorization. For role-based authorization, use the Roles parameter:
@page "/"
@attribute [Authorize(Roles = "Admin, Superuser")]
<p>You can only see this if you're in the 'Admin' or 'Superuser' role.</p>
For policy-based authorization, use the Policy parameter:
@page "/"
@attribute [Authorize(Policy = "Over21")]
<p>You can only see this if you satisfy the 'Over21' policy.</p>
In the following example, an EditUser policy is created in AuthorizationOptions for the app's authorization service configuration (AddAuthorizationCore) with the following logic:
Determine if a route value exists with a key of id. If the key exists, the route value is stored in value.
In a variable named id, store value as a string or set an empty string value (string.Empty).
If id isn't an empty string, assert that the policy is satisfied (return true) if the string's value starts with EMP. Otherwise, assert that the policy fails (return false).
using Microsoft.AspNetCore.Components;
using System.Linq;
Add the policy:
options.AddPolicy("EditUser", policy =>
policy.RequireAssertion(context =>
{
if (context.Resource is RouteData rd)
{
var routeValue = rd.RouteValues.TryGetValue("id", out var value);
var id = Convert.ToString(value,
System.Globalization.CultureInfo.InvariantCulture) ?? string.Empty;
if (!string.IsNullOrEmpty(id))
{
return id.StartsWith("EMP", StringComparison.InvariantCulture);
}
}
return false;
})
);
The preceding example is an oversimplified authorization policy, merely used to demonstrate the concept with a working example. For more information on creating and configuring authorization policies, see Policy-based authorization in ASP.NET Core.
In the following EditUser component, the resource at /users/{id}/edit has a route parameter for the user's identifier ({id}). The component uses the preceding EditUser authorization policy to determine if the route value for id starts with EMP. If id starts with EMP, the policy succeeds and access to the component is authorized. If id starts with a value other than EMP or if id is an empty string, the policy fails, and the component doesn't load.
EditUser.razor:
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]
<h1>Edit User</h1>
<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>
@code {
[Parameter]
public string? Id { get; set; }
}
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]
<h1>Edit User</h1>
<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>
@code {
[Parameter]
public string? Id { get; set; }
}
Customize unauthorized content with the Router component
The Router component, in conjunction with the AuthorizeRouteView component, allows the app to specify custom content if:
Asynchronous authorization is in progress, which usually means that the process of authenticating the user is in progress. The markup of the <Authorizing> element is displayed.
Important
Blazor router features that display <NotAuthorized> and <NotFound> content aren't operational during static server-side rendering (static SSR) because request processing is entirely handled by ASP.NET Core middleware pipeline request processing and Razor components aren't rendered at all for unauthorized or bad requests. Use server-side techniques to handle unauthorized and bad requests during static SSR. For more information, see ASP.NET Core Blazor render modes.
An app created from the Blazor WebAssembly project template with authentication enabled includes a RedirectToLogin component, which is positioned in the <NotAuthorized> content of the Router component. When a user isn't authenticated (context.User.Identity?.IsAuthenticated != true), the RedirectToLogin component redirects the browser to the authentication/login endpoint for authentication. The user is returned to the requested URL after authenticating with the identity provider.
Procedural logic
If the app is required to check authorization rules as part of procedural logic, use a cascaded parameter of type Task<AuthenticationState> to obtain the user's ClaimsPrincipal. Task<AuthenticationState> can be combined with other services, such as IAuthorizationService, to evaluate policies.
In the following example:
The user.Identity.IsAuthenticated executes code for authenticated (signed-in) users.
The user.IsInRole("admin") executes code for users in the 'Admin' role.
The (await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded executes code for users satisfying the 'content-editor' policy.
PII refers any information relating to an identified or identifiable natural person. An identifiable natural person is one who can be identified, directly or indirectly, with any of the following:
Using Forwarded Headers Middleware to preserve HTTPS scheme information across proxy servers and internal networks.
Additional scenarios and use cases, including manual scheme configuration, request path changes for correct request routing, and forwarding the request scheme for Linux and non-IIS reverse proxies.
Using Forwarded Headers Middleware to preserve HTTPS scheme information across proxy servers and internal networks.
Additional scenarios and use cases, including manual scheme configuration, request path changes for correct request routing, and forwarding the request scheme for Linux and non-IIS reverse proxies.
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, see our contributor guide.
ASP.NET Core feedback
ASP.NET Core is an open source project. Select a link to provide feedback: