diff --git a/aspnetcore/blazor/security/index.md b/aspnetcore/blazor/security/index.md
index 053854996f..7fb5948ff3 100644
--- a/aspnetcore/blazor/security/index.md
+++ b/aspnetcore/blazor/security/index.md
@@ -5,15 +5,13 @@ description: Learn about Blazor authentication and authorization scenarios.
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
-ms.date: 11/08/2022
+ms.date: 02/07/2023
uid: blazor/security/index
---
# ASP.NET Core Blazor authentication and authorization
This article describes ASP.NET Core's support for the configuration and management of security in Blazor apps.
-:::moniker range=">= aspnetcore-7.0"
-
Security scenarios differ between Blazor Server and Blazor WebAssembly apps. Because Blazor Server apps run on the server, authorization checks are able to determine:
* The UI options presented to a user (for example, which menu entries are available to a user).
@@ -21,58 +19,71 @@ Security scenarios differ between Blazor Server and Blazor WebAssembly apps. Bec
Blazor WebAssembly apps run on the client. Authorization is *only* used to determine which UI options to show. Since client-side checks can be modified or bypassed by a user, a Blazor WebAssembly app can't enforce authorization access rules.
-[Razor Pages authorization conventions](xref:security/authorization/razor-pages-authorization) don't apply to routable Razor components. If a non-routable Razor component is [embedded in a page](xref:blazor/components/prerendering-and-integration), the page's authorization conventions indirectly affect the Razor component along with the rest of the page's content.
+[Razor Pages authorization conventions](xref:security/authorization/razor-pages-authorization) don't apply to routable Razor components. If a non-routable Razor component is [embedded in a page of a Razor Pages app](xref:blazor/components/prerendering-and-integration), the page's authorization conventions indirectly affect the Razor component along with the rest of the page's content.
-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.
+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.
ASP.NET Core abstractions, such as and , aren't supported in Razor components. For more information on using ASP.NET Core Identity with Blazor, see [Scaffold ASP.NET Core Identity into a Blazor Server app](xref:security/authentication/scaffold-identity#scaffold-identity-into-a-blazor-server-project).
## Authentication
-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, Blazor WebAssembly or Blazor Server.
-
-### Blazor WebAssembly authentication
-
-In Blazor WebAssembly apps, 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 or native apps for any operating system.
-
-Add the following:
-
-* A package reference for [`Microsoft.AspNetCore.Components.Authorization`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.Authorization).
-
- [!INCLUDE[](~/includes/package-reference.md)]
-
-* The `Microsoft.AspNetCore.Components.Authorization` namespace to the app's `_Imports.razor` file.
-
-To handle authentication, use of a built-in or custom service is covered in the following sections.
-
-For more information on creating apps and configuration, see .
+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, Blazor Server or Blazor WebAssembly.
### Blazor Server authentication
-Blazor Server apps operate over a real-time connection that's created using SignalR. [Authentication in SignalR-based apps](xref:signalr/authn-and-authz) is handled when the connection is established. Authentication can be based on a cookie or some other bearer token.
+Blazor Server operates over a real-time connection that's created using SignalR. [Authentication in SignalR-based apps](xref:signalr/authn-and-authz) is handled when the connection is established. Authentication can be based on a cookie or some other bearer token.
The built-in service for Blazor Server apps obtains authentication state data from ASP.NET Core's `HttpContext.User`. This is how authentication state integrates with existing ASP.NET Core authentication mechanisms.
+Two additional abstractions participate in managing authentication state:
+
+* ([reference source](https://github.com/dotnet/aspnetcore/blob/main/src/Components/Server/src/Circuits/ServerAuthenticationStateProvider.cs)): An used by the Blazor framework to obtain authentication state from the server.
+* ([reference source](https://github.com/dotnet/aspnetcore/blob/main/src/Components/Server/src/Circuits/RevalidatingServerAuthenticationStateProvider.cs)): A base class for services used by the Blazor framework to receive an authentication state from the host environment and revalidate it at regular intervals.
+
+[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
+
> [!IMPORTANT]
> Don't use in Razor components of Blazor Server apps. Blazor apps run outside of the context of the ASP.NET Core pipeline. The isn't guaranteed to be available within the , and isn't guaranteed to hold the context that started the Blazor app. For more information, see [Security implications of using `IHttpContextAccessor` in Blazor Server (dotnet/aspnetcore #45699)](https://github.com/dotnet/aspnetcore/issues/45699). For more information on maintaining user state in Blazor Server apps, see .
-For more information on creating apps and configuration, see .
+For more information, see .
+
+### Blazor WebAssembly authentication
+
+In Blazor WebAssembly, 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.
+
+Add the following:
+
+* A package reference for the [`Microsoft.AspNetCore.Components.Authorization`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.Authorization) NuGet package.
+
+ [!INCLUDE[](~/includes/package-reference.md)]
+
+* The namespace to the app's `_Imports.razor` file.
+
+To handle authentication, use of the built-in or custom service is covered in the following sections.
+
+For more information, see .
## `AuthenticationStateProvider` service
- is the underlying service used by the component and component to get the authentication state.
+ is the underlying service used by the component and component to obtain the authentication state for a user.
You don't typically use directly. Use the [`AuthorizeView` component](#authorizeview-component) or [`Task`](#expose-the-authentication-state-as-a-cascading-parameter) approaches described later in this article. The main drawback to using directly is that the component isn't notified automatically if the underlying authentication state data changes.
-The service can provide the current user's data, as shown in the following example:
+> [!NOTE]
+> To implement a custom , see .
+
+The service can provide the current user's data, as shown in the following example.
+
+`Pages/ClaimsPrincipalData.razor`:
+
+:::moniker range=">= aspnetcore-6.0"
```razor
-@page "/"
+@page "/claims-principle-data"
@using System.Security.Claims
-@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
-
ClaimsPrincipal Data
+
ClaimsPrincipal Data
@@ -88,24 +99,24 @@ The
}
-
@surnameMessage
+
@surname
@code {
- private string authMessage;
- private string surnameMessage;
+ private string? authMessage;
+ private string? surname;
private IEnumerable claims = Enumerable.Empty();
private async Task GetClaimsPrincipalData()
{
- var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
+ var authState = await AuthenticationStateProvider
+ .GetAuthenticationStateAsync();
var user = authState.User;
- if (user.Identity.IsAuthenticated)
+ if (user.Identity is not null && user.Identity.IsAuthenticated)
{
authMessage = $"{user.Identity.Name} is authenticated.";
claims = user.Claims;
- surnameMessage =
- $"Surname: {user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value}";
+ surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
}
else
{
@@ -115,47 +126,145 @@ The ClaimsPrincipal Data
+
+
+
+
@authMessage
+
+@if (claims.Count() > 0)
+{
+
+ @foreach (var claim in claims)
+ {
+
@claim.Type: @claim.Value
+ }
+
+}
+
+
@surname
+
+@code {
+ private string authMessage;
+ private string surname;
+ private IEnumerable claims = Enumerable.Empty();
+
+ private async Task GetClaimsPrincipalData()
+ {
+ var authState = await AuthenticationStateProvider
+ .GetAuthenticationStateAsync();
+ var user = authState.User;
+
+ if (user.Identity.IsAuthenticated)
+ {
+ authMessage = $"{user.Identity.Name} is authenticated.";
+ claims = user.Claims;
+ surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
+ }
+ else
+ {
+ authMessage = "The user is NOT authenticated.";
+ }
+ }
+}
+```
+
+:::moniker-end
+
If `user.Identity.IsAuthenticated` is `true` and because the user is a , claims can be enumerated and membership in roles evaluated.
For more information on dependency injection (DI) and services, see and . For information on how to implement a custom in Blazor Server apps, see .
## 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<``>`:
+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](xref:blazor/components/cascading-values-and-parameters) of type `Task<``>`, as the following example demonstrates.
+
+`Pages/CascadeAuthState.razor`:
+
+:::moniker range=">= aspnetcore-6.0"
```razor
-@page "/"
+@page "/cascade-auth-state"
-
+
Cascade Auth State
@authMessage
@code {
+ private string authMessage = "The user is NOT authenticated.";
+
[CascadingParameter]
- private Task authenticationStateTask { get; set; }
+ private Task? authenticationState { get; set; }
- private string authMessage;
-
- private async Task LogUsername()
+ protected override async Task OnInitializedAsync()
{
- var authState = await authenticationStateTask;
- var user = authState.User;
+ if (authenticationState is not null)
+ {
+ var authState = await authenticationState;
+ var user = authState?.User;
- if (user.Identity.IsAuthenticated)
- {
- authMessage = $"{user.Identity.Name} is authenticated.";
- }
- else
- {
- authMessage = "The user is NOT authenticated.";
+ if (user?.Identity is not null && user.Identity.IsAuthenticated)
+ {
+ authMessage = $"{user.Identity.Name} is authenticated.";
+ }
}
}
}
```
+:::moniker-end
+
+:::moniker range="< aspnetcore-6.0"
+
+```razor
+@page "/cascade-auth-state"
+
+
Cascade Auth State
+
+
@authMessage
+
+@code {
+ private string authMessage = "The user is NOT authenticated.";
+
+ [CascadingParameter]
+ private Task 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.";
+ }
+ }
+ }
+}
+```
+
+:::moniker-end
+
If `user.Identity.IsAuthenticated` is `true`, claims can be enumerated and membership in roles evaluated.
-Set up the `Task<``>` cascading parameter using the and components in the `App` component (`App.razor`):
+Set up the `Task<``>` [cascading parameter](xref:blazor/components/cascading-values-and-parameters) using the and components in the `App` component.
+
+> [!NOTE]
+> When you create a Blazor app from one of the Blazor project templates with authentication enabled, the `App` component includes the and components shown in the following example. A Blazor WebAssembly app includes the required service registrations as well. Additional information is presented in the [Customize unauthorized content with the Router component](#customize-unauthorized-content-with-the-router-component) section.
+
+`App.razor`:
```razor
@@ -173,6 +282,12 @@ Set up the `Task<`
```
+:::moniker range="= aspnetcore-5.0"
+
+[!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]
+
+:::moniker-end
+
In a Blazor WebAssembly App, add services for options and authorization to `Program.cs`:
```csharp
@@ -180,7 +295,7 @@ builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
```
-In a Blazor Server app, services for options and authorization are already present, so no further action is required.
+In a Blazor Server app, services for options and authorization are already present, so no further steps are required.
## Authorization
@@ -195,11 +310,11 @@ Access is typically granted or denied based on whether:
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](xref:security/index).
-## AuthorizeView component
+## `AuthorizeView` component
The 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 , which you can use to access information about the signed-in user:
+The component exposes a `context` variable of type (`@context` in Razor syntax), which you can use to access information about the signed-in user:
```razor
@@ -228,10 +343,15 @@ You can also supply different content for display if the user isn't authorized:
}
```
-The content of `` and `` tags can include arbitrary items, such as other interactive components.
-
A default event handler for an authorized element, such as the `SecureMethod` method for the `
+
You can only see this if you satisfy the 'Over21' policy.
```
If neither nor is specified, [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) uses the default policy, which by default is to treat:
@@ -943,6 +554,14 @@ If neither no
* Authenticated (signed-in) users as authorized.
* Unauthenticated (signed-out) users as unauthorized.
+When the user isn't authorized, the framework automatically displays the following fallback message:
+
+```html
+Not authorized.
+```
+
+:::moniker range=">= aspnetcore-5.0"
+
## Resource authorization
To authorize users for resources, pass the request's route data to the parameter of .
@@ -1002,6 +621,10 @@ In the following `EditUser` component, the resource at `/users/{id}/edit` has a
`Pages/EditUser.razor`:
+:::moniker-end
+
+:::moniker range=">= aspnetcore-6.0"
+
```razor
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@@ -1009,567 +632,18 @@ In the following `EditUser` component, the resource at `/users/{id}/edit` has a
Edit User
-
The 'EditUser' policy is satisfied! Id starts with 'EMP'.
+
The "EditUser" policy is satisfied! Id starts with 'EMP'.
@code {
[Parameter]
- public string Id { get; set; }
+ public string? Id { get; set; }
}
```
-## Customize unauthorized content with the Router component
-
-The component, in conjunction with the component, allows the app to specify custom content if:
-
-* The user fails an [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) condition applied to the component. The markup of the [``](xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView.NotAuthorized?displayProperty=nameWithType) element is displayed. The [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) attribute is covered in the [`[Authorize]` attribute](#authorize-attribute) section.
-* Asynchronous authorization is in progress, which usually means that the process of authenticating the user is in progress. The markup of the [``](xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView.Authorizing?displayProperty=nameWithType) element is displayed.
-* Content isn't found. The markup of the [``](xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound?displayProperty=nameWithType) element is displayed.
-
-In the `App` component (`App.razor`):
-
-```
-
-
-
-
-
- ...
-
-
- ...
-
-
-
-
-
- ...
-
-
-
-
-```
-
-The content of ``, ``, and `` tags can include arbitrary items, such as other interactive components.
-
-If the `` tag isn't specified, the uses the following fallback message:
-
-```html
-Not authorized.
-```
-
-## Procedural logic
-
-If the app is required to check authorization rules as part of procedural logic, use a cascaded parameter of type `Task<``>` to obtain the user's . `Task<``>` can be combined with other services, such as `IAuthorizationService`, to evaluate policies.
-
-```razor
-@using Microsoft.AspNetCore.Authorization
-@inject IAuthorizationService AuthorizationService
-
-Do something important
-
-@code {
- [CascadingParameter]
- private Task authenticationStateTask { get; set; }
-
- private async Task DoSomething()
- {
- var user = (await authenticationStateTask).User;
-
- if (user.Identity.IsAuthenticated)
- {
- // Perform an action only available to authenticated (signed-in) users.
- }
-
- if (user.IsInRole("admin"))
- {
- // Perform an action only available to users in the 'admin' role.
- }
-
- if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
- .Succeeded)
- {
- // Perform an action only available to users satisfying the
- // 'content-editor' policy.
- }
- }
-}
-```
-
-> [!NOTE]
-> In a Blazor WebAssembly app component, add the and namespaces:
->
-> ```razor
-> @using Microsoft.AspNetCore.Authorization
-> @using Microsoft.AspNetCore.Components.Authorization
-> ```
->
-> These namespaces can be provided globally by adding them to the app's `_Imports.razor` file.
-
-## Troubleshoot errors
-
-Common errors:
-
-* **Authorization requires a cascading parameter of type `Task`. Consider using `CascadingAuthenticationState` to supply this.**
-
-* **`null` value is received for `authenticationStateTask`**
-
-It's likely that the project wasn't created using a Blazor Server template with authentication enabled. Wrap a `` around some part of the UI tree, for example in the `App` component (`App.razor`) as follows:
-
-```razor
-
-
- ...
-
-
-```
-
-The supplies the `Task<``>` cascading parameter, which in turn it receives from the underlying DI service.
-
-## Additional resources
-
-* Microsoft identity platform documentation
- * [Overview](/azure/active-directory/develop/)
- * [OAuth 2.0 and OpenID Connect protocols on the Microsoft identity platform](/azure/active-directory/develop/active-directory-v2-protocols)
- * [Microsoft identity platform and OAuth 2.0 authorization code flow](/azure/active-directory/develop/v2-oauth2-auth-code-flow)
- * [Microsoft identity platform ID tokens](/azure/active-directory/develop/id-tokens)
- * [Microsoft identity platform access tokens](/azure/active-directory/develop/access-tokens)
-*
-*
-* [Build a custom version of the Authentication.MSAL JavaScript library](xref:blazor/security/webassembly/additional-scenarios#build-a-custom-version-of-the-authenticationmsal-javascript-library)
-*
-* [Awesome Blazor: Authentication](https://github.com/AdrienTorris/awesome-blazor#authentication) community sample links
-
:::moniker-end
:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
-Security scenarios differ between Blazor Server and Blazor WebAssembly apps. Because Blazor Server apps run on the server, authorization checks are able to determine:
-
-* The UI options presented to a user (for example, which menu entries are available to a user).
-* Access rules for areas of the app and components.
-
-Blazor WebAssembly apps run on the client. Authorization is *only* used to determine which UI options to show. Since client-side checks can be modified or bypassed by a user, a Blazor WebAssembly app can't enforce authorization access rules.
-
-[Razor Pages authorization conventions](xref:security/authorization/razor-pages-authorization) don't apply to routable Razor components. If a non-routable Razor component is [embedded in a page](xref:blazor/components/prerendering-and-integration), the page's authorization conventions indirectly affect the Razor component along with the rest of the page's content.
-
-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.
-
-ASP.NET Core abstractions, such as and , aren't supported in Razor components. For more information on using ASP.NET Core Identity with Blazor, see [Scaffold ASP.NET Core Identity into a Blazor Server app](xref:security/authentication/scaffold-identity#scaffold-identity-into-a-blazor-server-project).
-
-## Authentication
-
-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, Blazor WebAssembly or Blazor Server.
-
-### Blazor WebAssembly authentication
-
-In Blazor WebAssembly apps, 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 or native apps for any operating system.
-
-Add the following:
-
-* A package reference for [`Microsoft.AspNetCore.Components.Authorization`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.Authorization).
-
- [!INCLUDE[](~/includes/package-reference.md)]
-
-* The `Microsoft.AspNetCore.Components.Authorization` namespace to the app's `_Imports.razor` file.
-
-To handle authentication, use of a built-in or custom service is covered in the following sections.
-
-For more information on creating apps and configuration, see .
-
-### Blazor Server authentication
-
-Blazor Server apps operate over a real-time connection that's created using SignalR. [Authentication in SignalR-based apps](xref:signalr/authn-and-authz) is handled when the connection is established. Authentication can be based on a cookie or some other bearer token.
-
-The built-in service for Blazor Server apps obtains authentication state data from ASP.NET Core's `HttpContext.User`. This is how authentication state integrates with existing ASP.NET Core authentication mechanisms.
-
-> [!IMPORTANT]
-> Don't use in Razor components of Blazor Server apps. Blazor apps run outside of the context of the ASP.NET Core pipeline. The isn't guaranteed to be available within the , and isn't guaranteed to hold the context that started the Blazor app. For more information, see [Security implications of using `IHttpContextAccessor` in Blazor Server (dotnet/aspnetcore #45699)](https://github.com/dotnet/aspnetcore/issues/45699). For more information on maintaining user state in Blazor Server apps, see .
-
-For more information on creating apps and configuration, see .
-
-## `AuthenticationStateProvider` service
-
- is the underlying service used by the component and component to get the authentication state.
-
-You don't typically use directly. Use the [`AuthorizeView` component](#authorizeview-component) or [`Task`](#expose-the-authentication-state-as-a-cascading-parameter) approaches described later in this article. The main drawback to using directly is that the component isn't notified automatically if the underlying authentication state data changes.
-
-The service can provide the current user's data, as shown in the following example:
-
-```razor
-@page "/"
-@using System.Security.Claims
-@using Microsoft.AspNetCore.Components.Authorization
-@inject AuthenticationStateProvider AuthenticationStateProvider
-
-
ClaimsPrincipal Data
-
-Get ClaimsPrincipal Data
-
-
@authMessage
-
-@if (claims.Count() > 0)
-{
-
- @foreach (var claim in claims)
- {
-
@claim.Type: @claim.Value
- }
-
-}
-
-
@surnameMessage
-
-@code {
- private string authMessage;
- private string surnameMessage;
- private IEnumerable claims = Enumerable.Empty();
-
- private async Task GetClaimsPrincipalData()
- {
- var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
- var user = authState.User;
-
- if (user.Identity.IsAuthenticated)
- {
- authMessage = $"{user.Identity.Name} is authenticated.";
- claims = user.Claims;
- surnameMessage =
- $"Surname: {user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value}";
- }
- else
- {
- authMessage = "The user is NOT authenticated.";
- }
- }
-}
-```
-
-If `user.Identity.IsAuthenticated` is `true` and because the user is a , claims can be enumerated and membership in roles evaluated.
-
-For more information on dependency injection (DI) and services, see and . For information on how to implement a custom in Blazor Server apps, see .
-
-## 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<``>`:
-
-```razor
-@page "/"
-
-Log username
-
-
@authMessage
-
-@code {
- [CascadingParameter]
- private Task authenticationStateTask { get; set; }
-
- private string authMessage;
-
- private async Task LogUsername()
- {
- var authState = await authenticationStateTask;
- var user = authState.User;
-
- if (user.Identity.IsAuthenticated)
- {
- authMessage = $"{user.Identity.Name} is authenticated.";
- }
- else
- {
- authMessage = "The user is NOT authenticated.";
- }
- }
-}
-```
-
-If `user.Identity.IsAuthenticated` is `true`, claims can be enumerated and membership in roles evaluated.
-
-Set up the `Task<``>` cascading parameter using the and components in the `App` component (`App.razor`):
-
-```razor
-
-
-
-
-
-
-
- ...
-
-
-
-
-```
-
-[!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]
-
-In a Blazor WebAssembly App, add services for options and authorization to `Program.cs`:
-
-```csharp
-builder.Services.AddOptions();
-builder.Services.AddAuthorizationCore();
-```
-
-In a Blazor Server app, services for options and authorization are already present, so no further action is 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](xref:security/index).
-
-## AuthorizeView component
-
-The 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 , which you can use to access information about the signed-in user:
-
-```razor
-
-
Hello, @context.User.Identity.Name!
-
You can only see this content if you're authenticated.
-
-```
-
-You can also supply different content for display if the user isn't authorized:
-
-```razor
-
-
-
Hello, @context.User.Identity.Name!
-
You can only see this content if you're authorized.
- Authorized Only Button
-
-
-
Authentication Failure!
-
You're not signed in.
-
-
-
-@code {
- private void SecureMethod() { ... }
-}
-```
-
-The content of `` and `` tags can include arbitrary items, such as other interactive components.
-
-A default event handler for an authorized element, such as the `SecureMethod` method for the `` element in the preceding example, can only be invoked by an authorized user.
-
-Authorization conditions, such as roles or policies that control UI options or access, are covered in the [Authorization](#authorization) section.
-
-If authorization conditions aren't specified, uses a default policy and treats:
-
-* Authenticated (signed-in) users as authorized.
-* Unauthenticated (signed-out) users as unauthorized.
-
-The component can be used in the `NavMenu` component (`Shared/NavMenu.razor`) to display a [`NavLink` component](xref:blazor/fundamentals/routing#navlink-and-navmenu-components) (), 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.
-
-Apps created from a [Blazor project template](xref:blazor/project-structure) that include authentication use a `LoginDisplay` component that depends on an `AuthorizeView` component. The `AuthorizeView` component selectively displays content to users for Identity-related work. The following example is from the [Blazor WebAssembly project template](xref:blazor/project-structure).
-
-`Shared/LoginDisplay.razor`:
-
-```razor
-@using Microsoft.AspNetCore.Components.Authorization
-@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
-
-@inject NavigationManager Navigation
-@inject SignOutSessionStateManager SignOutManager
-
-
-
- Hello, @context.User.Identity.Name!
- Log out
-
-
- Log in
-
-
-
-@code{
- private async Task BeginLogout(MouseEventArgs args)
- {
- await SignOutManager.SetSignOutState();
- Navigation.NavigateTo("authentication/logout");
- }
-}
-```
-
-The following example is from the [Blazor Server project template](xref:blazor/project-structure) and uses ASP.NET Core Identity endpoints in the `Identity` area of the app to process Identity-related work.
-
-`Shared/LoginDisplay.razor`:
-
-```razor
-
-
- Hello, @context.User.Identity.Name!
-
-
-
- Register
- Log in
-
-
-```
-
-### Role-based and policy-based authorization
-
-The component supports *role-based* or *policy-based* authorization.
-
-For role-based authorization, use the parameter. In the following example, the user must have a role claim for either (or both) the `Admin` or `Superuser` roles:
-
-```razor
-
-
You can only see this if you're an Admin or Superuser.
-
-```
-
-For more information, including configuration guidance, see .
-
-For policy-based authorization, use the parameter:
-
-```razor
-
-
You can only see this if you satisfy the "ContentEditor" policy.
-
-```
-
-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 .
-
-These APIs can be used in either Blazor Server or Blazor WebAssembly apps.
-
-If neither nor is specified, uses the default policy.
-
-Because .NET string comparisons are case-sensitive by default, 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 also unusual but permitted. For example, `billing administrator` is an unusual role or policy name format in .NET apps but valid.
-
-### Content displayed during asynchronous authentication
-
-Blazor allows for authentication state to be determined *asynchronously*. The primary scenario for this approach is in Blazor WebAssembly apps that make a request to an external endpoint for authentication.
-
-While authentication is in progress, displays no content by default. To display content while authentication occurs, use the `` tag:
-
-```razor
-
-
-
Hello, @context.User.Identity.Name!
-
You can only see this content if you're authenticated.
-
-
-
Authentication in progress
-
You can only see this content while authentication is in progress.
-
-
-```
-
-This approach isn't normally applicable to Blazor Server apps. Blazor Server apps know the authentication state as soon as the state is established. content can be provided in a Blazor Server app's component, but the content is never displayed.
-
-## [Authorize] attribute
-
-The [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) can be used in Razor components:
-
-```razor
-@page "/"
-@attribute [Authorize]
-
-You can only see this if you're signed in.
-```
-
-> [!IMPORTANT]
-> Only use [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) 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 instead.
-
-The [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) also supports role-based or policy-based authorization. For role-based authorization, use the parameter:
-
-```razor
-@page "/"
-@attribute [Authorize(Roles = "Admin, Superuser")]
-
-
You can only see this if you're in the 'Admin' or 'Superuser' role.
-```
-
-For policy-based authorization, use the parameter:
-
-```razor
-@page "/"
-@attribute [Authorize(Policy = "ContentEditor")]
-
-
You can only see this if you satisfy the 'ContentEditor' policy.
-```
-
-If neither nor is specified, [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) uses the default policy, which by default is to treat:
-
-* Authenticated (signed-in) users as authorized.
-* Unauthenticated (signed-out) users as unauthorized.
-
-## Resource authorization
-
-To authorize users for resources, pass the request's route data to the parameter of .
-
-In the content for a requested route in the `App` component (`App.razor`):
-
-```razor
-
-```
-
-For more information on how authorization state data is passed and used in procedural logic, see the [Expose the authentication state as a cascading parameter](#expose-the-authentication-state-as-a-cascading-parameter) section.
-
-When the receives the route data for the resource, authorization policies have access to and that permit custom logic to make authorization decisions.
-
-In the following example, an `EditUser` policy is created in for the app's authorization service configuration () 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`).
-
-In either `Program.cs` or `Startup.cs` (depending on the hosting model and framework version):
-
-* Add namespaces for and :
-
- ```csharp
- using Microsoft.AspNetCore.Components;
- using System.Linq;
- ```
-
-* Add the policy:
-
- ```csharp
- 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 .
-
-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.
-
-`Pages/EditUser.razor`:
-
```razor
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@@ -1577,7 +651,7 @@ In the following `EditUser` component, the resource at `/users/{id}/edit` has a
Edit User
-
The 'EditUser' policy is satisfied! Id starts with 'EMP'.
+
The "EditUser" policy is satisfied! Id starts with 'EMP'.
@code {
[Parameter]
@@ -1585,6 +659,8 @@ In the following `EditUser` component, the resource at `/users/{id}/edit` has a
}
```
+:::moniker-end
+
## Customize unauthorized content with the Router component
The component, in conjunction with the component, allows the app to specify custom content if:
@@ -1617,8 +693,6 @@ In the `App` component (`App.razor`):
```
-[!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]
-
The content of ``, ``, and `` tags can include arbitrary items, such as other interactive components.
If the `` tag isn't specified, the uses the following fallback message:
@@ -1631,6 +705,63 @@ Not authorized.
If the app is required to check authorization rules as part of procedural logic, use a cascaded parameter of type `Task<``>` to obtain the user's . `Task<``>` 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.
+
+`Pages/ProceduralLogic.razor`:
+
+:::moniker range=">= aspnetcore-6.0"
+
+```razor
+@page "/procedural-logic"
+@using Microsoft.AspNetCore.Authorization
+@inject IAuthorizationService AuthorizationService
+
+
Procedural Logic Example
+
+Do something important
+
+@code {
+ [CascadingParameter]
+ private Task? authenticationState { get; set; }
+
+ private async Task DoSomething()
+ {
+ if (authenticationState is not null)
+ {
+ var authState = await authenticationState;
+ var user = authState?.User;
+
+ if (user is not null)
+ {
+ if (user.Identity is not null && user.Identity.IsAuthenticated)
+ {
+ ...
+ }
+
+ if (user.IsInRole("Admin"))
+ {
+ ...
+ }
+
+ if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
+ .Succeeded)
+ {
+ ...
+ }
+ }
+ }
+ }
+}
+```
+
+:::moniker-end
+
+:::moniker range="< aspnetcore-6.0"
+
```razor
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService
@@ -1647,33 +778,32 @@ If the app is required to check authorization rules as part of procedural logic,
if (user.Identity.IsAuthenticated)
{
- // Perform an action only available to authenticated (signed-in) users.
+ ...
}
- if (user.IsInRole("admin"))
+ if (user.IsInRole("Admin"))
{
- // Perform an action only available to users in the 'admin' role.
+ ...
}
if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
.Succeeded)
{
- // Perform an action only available to users satisfying the
- // 'content-editor' policy.
+ ...
}
}
}
```
+:::moniker-end
+
> [!NOTE]
-> In a Blazor WebAssembly app component, add the and namespaces:
+> In a Blazor WebAssembly app, confirm the presence of the and namespaces either in the component or in the app's `_Imports.razor` file:
>
> ```razor
> @using Microsoft.AspNetCore.Authorization
> @using Microsoft.AspNetCore.Components.Authorization
> ```
->
-> These namespaces can be provided globally by adding them to the app's `_Imports.razor` file.
## Troubleshoot errors
@@ -1693,12 +823,28 @@ It's likely that the project wasn't created using a Blazor Server template with
```
-[!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]
-
-The supplies the `Task<``>` cascading parameter, which in turn it receives from the underlying DI service.
+The supplies the `Task<``>` cascading parameter, which in turn it receives from the underlying dependency injection service.
## Additional resources
+:::moniker range=">= aspnetcore-6.0"
+
+* Microsoft identity platform documentation
+ * [Overview](/azure/active-directory/develop/)
+ * [OAuth 2.0 and OpenID Connect protocols on the Microsoft identity platform](/azure/active-directory/develop/active-directory-v2-protocols)
+ * [Microsoft identity platform and OAuth 2.0 authorization code flow](/azure/active-directory/develop/v2-oauth2-auth-code-flow)
+ * [Microsoft identity platform ID tokens](/azure/active-directory/develop/id-tokens)
+ * [Microsoft identity platform access tokens](/azure/active-directory/develop/access-tokens)
+*
+*
+* [Build a custom version of the Authentication.MSAL JavaScript library](xref:blazor/security/webassembly/additional-scenarios#build-a-custom-version-of-the-authenticationmsal-javascript-library)
+* [Awesome Blazor: Authentication](https://github.com/AdrienTorris/awesome-blazor#authentication) community sample links
+*
+
+:::moniker-end
+
+:::moniker range="< aspnetcore-6.0"
+
* Microsoft identity platform documentation
* [Overview](/azure/active-directory/develop/)
* [OAuth 2.0 and OpenID Connect protocols on the Microsoft identity platform](/azure/active-directory/develop/active-directory-v2-protocols)
@@ -1711,489 +857,3 @@ The and , aren't supported in Razor components. For more information on using ASP.NET Core Identity with Blazor, see [Scaffold ASP.NET Core Identity into a Blazor Server app](xref:security/authentication/scaffold-identity#scaffold-identity-into-a-blazor-server-project).
-
-## Authentication
-
-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, Blazor WebAssembly or Blazor Server.
-
-### Blazor WebAssembly authentication
-
-In Blazor WebAssembly apps, 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 or native apps for any operating system.
-
-Add the following:
-
-* A package reference for [`Microsoft.AspNetCore.Components.Authorization`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.Authorization).
-
- [!INCLUDE[](~/includes/package-reference.md)]
-
-* The `Microsoft.AspNetCore.Components.Authorization` namespace to the app's `_Imports.razor` file.
-
-To handle authentication, use of a built-in or custom service is covered in the following sections.
-
-For more information on creating apps and configuration, see .
-
-### Blazor Server authentication
-
-Blazor Server apps operate over a real-time connection that's created using SignalR. [Authentication in SignalR-based apps](xref:signalr/authn-and-authz) is handled when the connection is established. Authentication can be based on a cookie or some other bearer token.
-
-The built-in service for Blazor Server apps obtains authentication state data from ASP.NET Core's `HttpContext.User`. This is how authentication state integrates with existing ASP.NET Core authentication mechanisms.
-
-> [!IMPORTANT]
-> Don't use in Razor components of Blazor Server apps. Blazor apps run outside of the context of the ASP.NET Core pipeline. The isn't guaranteed to be available within the , and isn't guaranteed to hold the context that started the Blazor app. For more information, see [Security implications of using `IHttpContextAccessor` in Blazor Server (dotnet/aspnetcore #45699)](https://github.com/dotnet/aspnetcore/issues/45699). For more information on maintaining user state in Blazor Server apps, see .
-
-For more information on creating apps and configuration, see .
-
-## `AuthenticationStateProvider` service
-
- is the underlying service used by the component and component to get the authentication state.
-
-You don't typically use directly. Use the [`AuthorizeView` component](#authorizeview-component) or [`Task`](#expose-the-authentication-state-as-a-cascading-parameter) approaches described later in this article. The main drawback to using directly is that the component isn't notified automatically if the underlying authentication state data changes.
-
-The service can provide the current user's data, as shown in the following example:
-
-```razor
-@page "/"
-@using System.Security.Claims
-@using Microsoft.AspNetCore.Components.Authorization
-@inject AuthenticationStateProvider AuthenticationStateProvider
-
-
ClaimsPrincipal Data
-
-Get ClaimsPrincipal Data
-
-
@authMessage
-
-@if (claims.Count() > 0)
-{
-
- @foreach (var claim in claims)
- {
-
@claim.Type: @claim.Value
- }
-
-}
-
-
@surnameMessage
-
-@code {
- private string authMessage;
- private string surnameMessage;
- private IEnumerable claims = Enumerable.Empty();
-
- private async Task GetClaimsPrincipalData()
- {
- var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
- var user = authState.User;
-
- if (user.Identity.IsAuthenticated)
- {
- authMessage = $"{user.Identity.Name} is authenticated.";
- claims = user.Claims;
- surnameMessage =
- $"Surname: {user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value}";
- }
- else
- {
- authMessage = "The user is NOT authenticated.";
- }
- }
-}
-```
-
-If `user.Identity.IsAuthenticated` is `true` and because the user is a , claims can be enumerated and membership in roles evaluated.
-
-For more information on dependency injection (DI) and services, see and . For information on how to implement a custom in Blazor Server apps, see .
-
-## 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<``>`:
-
-```razor
-@page "/"
-
-Log username
-
-
@authMessage
-
-@code {
- [CascadingParameter]
- private Task authenticationStateTask { get; set; }
-
- private string authMessage;
-
- private async Task LogUsername()
- {
- var authState = await authenticationStateTask;
- var user = authState.User;
-
- if (user.Identity.IsAuthenticated)
- {
- authMessage = $"{user.Identity.Name} is authenticated.";
- }
- else
- {
- authMessage = "The user is NOT authenticated.";
- }
- }
-}
-```
-
-If `user.Identity.IsAuthenticated` is `true`, claims can be enumerated and membership in roles evaluated.
-
-Set up the `Task<``>` cascading parameter using the and components in the `App` component (`App.razor`):
-
-```razor
-
-
-
-
-
-
-
- ...
-
-
-
-
-```
-
-In a Blazor WebAssembly App, add services for options and authorization to `Program.cs`:
-
-```csharp
-builder.Services.AddOptions();
-builder.Services.AddAuthorizationCore();
-```
-
-In a Blazor Server app, services for options and authorization are already present, so no further action is 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](xref:security/index).
-
-## AuthorizeView component
-
-The 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 , which you can use to access information about the signed-in user:
-
-```razor
-
-
Hello, @context.User.Identity.Name!
-
You can only see this content if you're authenticated.
-
-```
-
-You can also supply different content for display if the user isn't authorized:
-
-```razor
-
-
-
Hello, @context.User.Identity.Name!
-
You can only see this content if you're authorized.
- Authorized Only Button
-
-
-
Authentication Failure!
-
You're not signed in.
-
-
-
-@code {
- private void SecureMethod() { ... }
-}
-```
-
-The content of `` and `` tags can include arbitrary items, such as other interactive components.
-
-A default event handler for an authorized element, such as the `SecureMethod` method for the `` element in the preceding example, can only be invoked by an authorized user.
-
-Authorization conditions, such as roles or policies that control UI options or access, are covered in the [Authorization](#authorization) section.
-
-If authorization conditions aren't specified, uses a default policy and treats:
-
-* Authenticated (signed-in) users as authorized.
-* Unauthenticated (signed-out) users as unauthorized.
-
-The component can be used in the `NavMenu` component (`Shared/NavMenu.razor`) to display a [`NavLink` component](xref:blazor/fundamentals/routing#navlink-and-navmenu-components) (), 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.
-
-Apps created from a [Blazor project template](xref:blazor/project-structure) that include authentication use a `LoginDisplay` component that depends on an `AuthorizeView` component. The `AuthorizeView` component selectively displays content to users for Identity-related work. The following example is from the [Blazor WebAssembly project template](xref:blazor/project-structure).
-
-`Shared/LoginDisplay.razor`:
-
-```razor
-@using Microsoft.AspNetCore.Components.Authorization
-@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
-
-@inject NavigationManager Navigation
-@inject SignOutSessionStateManager SignOutManager
-
-
-
- Hello, @context.User.Identity.Name!
- Log out
-
-
- Log in
-
-
-
-@code{
- private async Task BeginLogout(MouseEventArgs args)
- {
- await SignOutManager.SetSignOutState();
- Navigation.NavigateTo("authentication/logout");
- }
-}
-```
-
-The following example is from the [Blazor Server project template](xref:blazor/project-structure) and uses ASP.NET Core Identity endpoints in the `Identity` area of the app to process Identity-related work.
-
-`Shared/LoginDisplay.razor`:
-
-```razor
-
-
- Hello, @context.User.Identity.Name!
-
-
-
- Register
- Log in
-
-
-```
-
-### Role-based and policy-based authorization
-
-The component supports *role-based* or *policy-based* authorization.
-
-For role-based authorization, use the parameter. In the following example, the user must have a role claim for either (or both) the `Admin` or `Superuser` roles:
-
-```razor
-
-
You can only see this if you're an Admin or Superuser.
-
-```
-
-For more information, including configuration guidance, see .
-
-For policy-based authorization, use the parameter:
-
-```razor
-
-
You can only see this if you satisfy the "ContentEditor" policy.
-
-```
-
-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 .
-
-These APIs can be used in either Blazor Server or Blazor WebAssembly apps.
-
-If neither nor is specified, uses the default policy.
-
-Because .NET string comparisons are case-sensitive by default, 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 also unusual but permitted. For example, `billing administrator` is an unusual role or policy name format in .NET apps but valid.
-
-### Content displayed during asynchronous authentication
-
-Blazor allows for authentication state to be determined *asynchronously*. The primary scenario for this approach is in Blazor WebAssembly apps that make a request to an external endpoint for authentication.
-
-While authentication is in progress, displays no content by default. To display content while authentication occurs, use the `` tag:
-
-```razor
-
-
-
Hello, @context.User.Identity.Name!
-
You can only see this content if you're authenticated.
-
-
-
Authentication in progress
-
You can only see this content while authentication is in progress.
-
-
-```
-
-This approach isn't normally applicable to Blazor Server apps. Blazor Server apps know the authentication state as soon as the state is established. content can be provided in a Blazor Server app's component, but the content is never displayed.
-
-## [Authorize] attribute
-
-The [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) can be used in Razor components:
-
-```razor
-@page "/"
-@attribute [Authorize]
-
-You can only see this if you're signed in.
-```
-
-> [!IMPORTANT]
-> Only use [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) 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 instead.
-
-The [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) also supports role-based or policy-based authorization. For role-based authorization, use the parameter:
-
-```razor
-@page "/"
-@attribute [Authorize(Roles = "Admin, Superuser")]
-
-
You can only see this if you're in the 'Admin' or 'Superuser' role.
-```
-
-For policy-based authorization, use the parameter:
-
-```razor
-@page "/"
-@attribute [Authorize(Policy = "ContentEditor")]
-
-
You can only see this if you satisfy the 'ContentEditor' policy.
-```
-
-If neither nor is specified, [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) uses the default policy, which by default is to treat:
-
-* Authenticated (signed-in) users as authorized.
-* Unauthenticated (signed-out) users as unauthorized.
-
-## Customize unauthorized content with the Router component
-
-The component, in conjunction with the component, allows the app to specify custom content if:
-
-* The user fails an [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) condition applied to the component. The markup of the [``](xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView.NotAuthorized?displayProperty=nameWithType) element is displayed. The [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) attribute is covered in the [`[Authorize]` attribute](#authorize-attribute) section.
-* Asynchronous authorization is in progress, which usually means that the process of authenticating the user is in progress. The markup of the [``](xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView.Authorizing?displayProperty=nameWithType) element is displayed.
-* Content isn't found. The markup of the [``](xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound?displayProperty=nameWithType) element is displayed.
-
-In the `App` component (`App.razor`):
-
-```razor
-
-
-
-
-
- ...
-
-
- ...
-
-
-
-
-
- ...
-
-
-
-
-```
-
-The content of ``, ``, and `` tags can include arbitrary items, such as other interactive components.
-
-If the `` tag isn't specified, the uses the following fallback message:
-
-```html
-Not authorized.
-```
-
-## Procedural logic
-
-If the app is required to check authorization rules as part of procedural logic, use a cascaded parameter of type `Task<``>` to obtain the user's . `Task<``>` can be combined with other services, such as `IAuthorizationService`, to evaluate policies.
-
-```razor
-@using Microsoft.AspNetCore.Authorization
-@inject IAuthorizationService AuthorizationService
-
-Do something important
-
-@code {
- [CascadingParameter]
- private Task authenticationStateTask { get; set; }
-
- private async Task DoSomething()
- {
- var user = (await authenticationStateTask).User;
-
- if (user.Identity.IsAuthenticated)
- {
- // Perform an action only available to authenticated (signed-in) users.
- }
-
- if (user.IsInRole("admin"))
- {
- // Perform an action only available to users in the 'admin' role.
- }
-
- if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
- .Succeeded)
- {
- // Perform an action only available to users satisfying the
- // 'content-editor' policy.
- }
- }
-}
-```
-
-> [!NOTE]
-> In a Blazor WebAssembly app component, add the and namespaces:
->
-> ```razor
-> @using Microsoft.AspNetCore.Authorization
-> @using Microsoft.AspNetCore.Components.Authorization
-> ```
->
-> These namespaces can be provided globally by adding them to the app's `_Imports.razor` file.
-
-## Troubleshoot errors
-
-Common errors:
-
-* **Authorization requires a cascading parameter of type `Task`. Consider using `CascadingAuthenticationState` to supply this.**
-
-* **`null` value is received for `authenticationStateTask`**
-
-It's likely that the project wasn't created using a Blazor Server template with authentication enabled. Wrap a `` around some part of the UI tree, for example in the `App` component (`App.razor`) as follows:
-
-```razor
-
-
- ...
-
-
-```
-
-The supplies the `Task<``>` cascading parameter, which in turn it receives from the underlying DI service.
-
-## Additional resources
-
-* [Microsoft identity platform documentation](/azure/active-directory/develop/)
-*
-*
-* [Build a custom version of the Authentication.MSAL JavaScript library](xref:blazor/security/webassembly/additional-scenarios#build-a-custom-version-of-the-authenticationmsal-javascript-library)
-* [Awesome Blazor: Authentication](https://github.com/AdrienTorris/awesome-blazor#authentication) community sample links
-
-:::moniker-end
diff --git a/aspnetcore/blazor/security/webassembly/additional-scenarios.md b/aspnetcore/blazor/security/webassembly/additional-scenarios.md
index 388d532cbf..c71aa36f15 100644
--- a/aspnetcore/blazor/security/webassembly/additional-scenarios.md
+++ b/aspnetcore/blazor/security/webassembly/additional-scenarios.md
@@ -1032,6 +1032,8 @@ builder.Services.TryAddScoped.
+
In the **:::no-loc text="Server":::** project's `Pages/_Host.cshtml` file, replace the `Component` Tag Helper (``) with the following:
```cshtml
@@ -2259,7 +2261,7 @@ builder.Services.AddScoped();
Client.Program.ConfigureCommonServices(services);
```
-For more information on the Blazor framework server authentication provider (`ServerAuthenticationStateProvider`), see [`ServerAuthenticationStateProvider` (API documentation)](xref:Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider) and [`ServerAuthenticationStateProvider` (reference source)](https://github.com/dotnet/aspnetcore/blob/main/src/Components/Server/src/Circuits/ServerAuthenticationStateProvider.cs).
+For more information on the Blazor framework server authentication provider (`ServerAuthenticationStateProvider`), see .
[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
@@ -3490,7 +3492,7 @@ public void ConfigureServices(IServiceCollection services)
}
```
-For more information on the Blazor framework server authentication provider (`ServerAuthenticationStateProvider`), see [`ServerAuthenticationStateProvider` (API documentation)](xref:Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider) and [`ServerAuthenticationStateProvider` (reference source)](https://github.com/dotnet/aspnetcore/blob/main/src/Components/Server/src/Circuits/ServerAuthenticationStateProvider.cs).
+For more information on the Blazor framework server authentication provider (`ServerAuthenticationStateProvider`), see .
[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
@@ -4721,7 +4723,7 @@ public void ConfigureServices(IServiceCollection services)
}
```
-For more information on the Blazor framework server authentication provider (`ServerAuthenticationStateProvider`), see [`ServerAuthenticationStateProvider` (API documentation)](xref:Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider) and [`ServerAuthenticationStateProvider` (reference source)](https://github.com/dotnet/aspnetcore/blob/main/src/Components/Server/src/Circuits/ServerAuthenticationStateProvider.cs).
+For more information on the Blazor framework server authentication provider (`ServerAuthenticationStateProvider`), see .
[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
diff --git a/aspnetcore/blazor/webassembly-lazy-load-assemblies.md b/aspnetcore/blazor/webassembly-lazy-load-assemblies.md
index 005bd3bedf..cf307fbea5 100644
--- a/aspnetcore/blazor/webassembly-lazy-load-assemblies.md
+++ b/aspnetcore/blazor/webassembly-lazy-load-assemblies.md
@@ -128,7 +128,7 @@ In the following example:
> [!NOTE]
> The preceding example doesn't show the contents of the `Router` component's Razor markup (`...`). For a demonstration with complete code, see the [Complete example](#complete-example) section of this article.
-:::moniker range="< aspnetcore-6.0"
+:::moniker range="= aspnetcore-5.0"
[!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]
@@ -229,7 +229,7 @@ In the following example:
> [!NOTE]
> The preceding example doesn't show the contents of the `Router` component's Razor markup (`...`). For a demonstration with complete code, see the [Complete example](#complete-example) section of this article.
-:::moniker range="< aspnetcore-6.0"
+:::moniker range="= aspnetcore-5.0"
[!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]