Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
En este artículo se describe la compatibilidad de ASP.NET Core con la configuración y administración de la seguridad en aplicaciones Blazor.
Blazor usa los mecanismos de autenticación de ASP.NET Core existentes para establecer la identity del usuario. El mecanismo exacto depende de cómo esté hospedada la aplicación Blazor, del lado servidor o del lado cliente.
Los escenarios de seguridad difieren entre el código de autorización que se ejecuta en el lado servidor y el lado cliente en aplicaciones Blazor. Para el código de autorización que se ejecuta en el servidor, las comprobaciones de autorización pueden aplicar reglas de acceso para las áreas de la aplicación y los componentes. Como la ejecución de código del lado cliente se puede alterar, el código de autorización que se ejecuta en el cliente no puede ser de confianza para aplicar absolutamente reglas de acceso ni controlar la visualización del contenido del lado cliente.
Si se debe garantizar la aplicación de reglas de autorización, no implemente comprobaciones de autorización en el código del lado cliente. Compila Blazor Web App que solo se base en la representación del lado servidor (SSR) para las comprobaciones de autorización y la aplicación de reglas.
Si se debe garantizar la aplicación de reglas de autorización y la seguridad de los datos y el código, no desarrolle una aplicación del lado cliente. Compile una aplicación de Blazor Server.
ASP.NET Core Identity está diseñado para funcionar en el contexto de la comunicación de solicitud y respuesta HTTP, que por lo general no es el modelo de comunicación de cliente-servidor de Blazor aplicación. ASP.NET Aplicaciones principales que usan ASP.NET Core Identity para la administración de usuarios deben usar Razor Pages en lugar de componentes de Razor para Identityinterfaz de usuario relacionada, como el registro de usuarios, el inicio de sesión, el cierre de sesión y otras tareas de administración de usuarios. La creación de componentes de Razor que controlan tareas de Identity directamente es posible en varios escenarios, pero Microsoft no lo recomienda ni admite.
Mantener de forma segura la información confidencial y las credenciales
No almacene secretos de aplicación, cadena de conexión, credenciales, contraseñas, números de identificación personal (PIN), código .NET/C# privado o claves o tokens privados en código del lado cliente, lo que siempre es inseguro. El código del lado Blazor cliente debe acceder a servicios y bases de datos seguros a través de una API web segura que controle.
En entornos de prueba/ensayo y producción, el código del lado Blazor servidor y las API web deben usar flujos de autenticación seguros que eviten mantener las credenciales dentro del código del proyecto o los archivos de configuración. Fuera de las pruebas de desarrollo local, se recomienda evitar el uso de variables de entorno para almacenar datos confidenciales, ya que las variables de entorno no son el enfoque más seguro. Para las pruebas de desarrollo local, se recomienda la herramienta Secret Manager para proteger los datos confidenciales. Para obtener más información, consulte los siguientes recursos:
Para el desarrollo y las pruebas locales del lado cliente y del lado servidor, use la herramienta Administrador de secretos para proteger las credenciales confidenciales.
Identidades administradas para servicios de Microsoft Azure
Para los servicios de Microsoft Azure, se recomienda usar identidades administradas. Las identidades administradas proporcionan una autenticación segura en los servicios de Azure sin almacenar credenciales en el código de la aplicación. Para obtener más información, consulte los siguientes recursos:
Blazor almacena tokens de solicitud en estado de componente, lo que garantiza que los tokens de antifalsificación están disponibles para los componentes interactivos, incluso cuando no tienen acceso a la solicitud.
Las aplicaciones de Blazor del lado servidor están configuradas para la seguridad, de la misma manera que las aplicaciones ASP.NET Core. Para obtener más información, consulte los artículos disponibles en Temas de seguridad de ASP.NET Core.
El contexto de autenticación solo se establece cuando se inicia la aplicación, que es cuando la aplicación se conecta por primera vez a WebSocket a través de una SignalR conexión con el cliente. La autenticación se puede basar en una cookie o algún otro token de portador, pero la autenticación se administra a través del centro de SignalR y completamente dentro del circuito. El contexto de la autenticación se mantiene durante la vigencia del circuito. Las aplicaciones vuelven a validar periódicamente el estado de autenticación del usuario cada 30 minutos.
Si la aplicación debe capturar usuarios para servicios personalizados o reaccionar a las actualizaciones del usuario, consulte Blazor Web App de seguridad adicionales y del lado servidor core.
Blazor difiere de una aplicación web representada por el servidor tradicional que realiza nuevas solicitudes HTTP con cookies en cada navegación de página. La autenticación se comprueba durante los eventos de navegación. Sin embargo, no se tienen en cuenta las cookies. Las cookies solo se envían al realizar una solicitud HTTP a un servidor, lo cual no sucede cuando el usuario navega en una aplicación de Blazor. Durante la navegación, el estado de la autenticación del usuario se comprueba dentro del circuito de Blazor, que puede actualizar en cualquier momento en el servidor mediante la abstracción del RevalidatingAuthenticationStateProvider.
Importante
No se recomienda implementar un NavigationManager personalizado para lograr la validación de autenticación durante la navegación. Si la aplicación debe ejecutar la lógica de estado de autenticación personalizada durante la navegación, use un AuthenticationStateProvider personalizado.
El servicio personalizado AuthenticationStateProvider integrado obtiene datos de estado de autenticación de HttpContext.User de ASP.NET Core. Así es como el estado de autenticación se integra con los mecanismos de autenticación de ASP.NET Core.
Para obtener más información sobre la autenticación del lado servidor, consulte Blazor principales.
IHttpContextAccessor/HttpContext en Razor componentes
IHttpContextAccessor debe evitarse con la representación interactiva porque no hay un HttpContext válido disponible.
IHttpContextAccessor se puede usar para los componentes que se representan estáticamente en el servidor. Sin embargo, se recomienda evitarlo si es posible.
HttpContextse puede usar como parámetro en cascada solo en componentes raíz representados estáticamente para tareas generales, como inspeccionar y modificar encabezados u otras propiedades del componente App (Components/App.razor). El valor siempre es null para la representación interactiva.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
En escenarios en los que se requiere el HttpContext en componentes interactivos, se recomienda hacer fluir los datos a través del estado del componente persistente desde el servidor. Para obtener más información, consulte Blazor Web App de seguridad adicionales y del lado servidor principal.
No use IHttpContextAccessor/HttpContext directa o indirectamente en los componentes Razor de las aplicaciones Blazor del lado servidor. Las aplicaciones de Blazor se ejecutan fuera del contexto de la canalización de ASP.NET Core. No se garantiza que HttpContext esté disponible en IHttpContextAccessor, ni tampoco que HttpContext contenga el contexto que ha iniciado la aplicación de Blazor.
El enfoque recomendado para pasar el estado de solicitud a la aplicación de Blazor es a través de parámetros de componente raíz durante la representación inicial de la aplicación. Como alternativa, la aplicación puede copiar los datos en un servicio con ámbito en el evento de ciclo de vida de inicialización del componente raíz para usarlos en toda la aplicación. Para obtener más información, consulte Blazor Web App de seguridad adicionales y del lado servidor principal.
Un aspecto crítico de la seguridad de Blazor en el lado del servidor es que el usuario asociado a un circuito determinado se puede actualizar en algún momento después de que se establezca el circuito de Blazor, pero IHttpContextAccessorno se actualice. Para obtener más información sobre cómo abordar esta situación con servicios personalizados, consulte Blazor Web App de seguridad adicionales y del lado servidor principal.
Estado compartido
Las aplicaciones Blazor del lado servidor residen en la memoria del servidor, y varias sesiones de aplicación se hospedan en el mismo proceso. Para cada sesión de aplicación, Blazor inicia un circuito con su propio ámbito de contenedor de inserción de dependencias, por lo que los servicios con ámbito son únicos para cada sesión de Blazor.
Advertencia
No se recomienda que las aplicaciones del mismo servidor compartan estado mediante servicios singleton, a menos que se tomen precauciones, ya que esto puede incorporar vulnerabilidades de seguridad, como la pérdida de estado de usuario entre circuitos.
Puede usar servicios singleton con estado en aplicaciones de Blazor si están específicamente diseñadas para ello. Por ejemplo, el uso de una caché de memoria singleton es aceptable porque una memoria caché requiere una clave para acceder a una entrada determinada. Suponiendo que los usuarios no tengan control sobre las claves de caché que se usan con la memoria caché, el estado almacenado en la memoria caché no se filtra entre circuitos.
Seguridad del lado servidor de datos confidenciales y credenciales
En entornos de prueba/ensayo y producción, el código del lado Blazor servidor y las API web deben usar flujos de autenticación seguros que eviten mantener las credenciales dentro del código del proyecto o los archivos de configuración. Fuera de las pruebas de desarrollo local, se recomienda evitar el uso de variables de entorno para almacenar datos confidenciales, ya que las variables de entorno no son el enfoque más seguro. Para las pruebas de desarrollo local, se recomienda la herramienta Secret Manager para proteger los datos confidenciales. Para obtener más información, consulte los siguientes recursos:
Para el desarrollo y las pruebas locales del lado cliente y del lado servidor, use la herramienta Administrador de secretos para proteger las credenciales confidenciales.
Después de elegir la plantilla de aplicación del lado servidor y configurar el proyecto, seleccione la autenticación de la aplicación en Tipo de autenticación:
Ninguno (predeterminado): no hay autenticación.
Cuentas individuales: las cuentas de usuario se almacenan en la aplicación mediante Identity en ASP.NET Core.
Ninguno (predeterminado): no hay autenticación.
Cuentas individuales: las cuentas de usuario se almacenan en la aplicación mediante Identity en ASP.NET Core.
Al emitir el comando de la CLI de .NET para crear y configurar la aplicación de Blazor del lado servidor, indique el mecanismo de autenticación con la opción -au|--auth:
Para más información, consulte el comando dotnet new de la guía de .NET Core.
Al emitir el comando de la CLI de .NET para crear y configurar la aplicación de Blazor del lado servidor, indique el mecanismo de autenticación con la opción -au|--auth:
Consulte el comando dotnet new en la guía de .NET Core.
Ejecute el comando de ayuda para la plantilla en un shell de comandos:
dotnet new {PROJECT TEMPLATE} --help
En el comando anterior, el marcador de posición {PROJECT TEMPLATE} es la plantilla de proyecto.
BlazorIdentityUI (cuentas individuales)
Blazor admite la generación de una interfaz de usuario completa basada en BlazorIdentity al elegir la opción de autenticación para cuentas individuales.
La plantilla de Blazor Web App sirve de andamiaje para el código de Identity para una base de datos de SQL Server. La versión de la línea de comandos usa SQLite e incluye una base de datos de SQLite para Identity.
La plantilla :
Admite escenarios de representación interactiva del lado servidor (SSR interactiva) y representación del lado cliente (CSR) con usuarios autenticados.
Agrega componentes de IdentityRazor y lógica relacionada para tareas de autenticación rutinarias, como iniciar y cerrar sesión de usuarios. Los componentes de Identity también admiten características de Identity avanzadas, como confirmación de cuenta y recuperación de contraseña y autenticación multifactor mediante una aplicación de terceros. Ten en cuenta que los propios componentes de Identity no admiten interactividad.
Agrega los paquetes y dependencias relacionados con Identity.
Hace referencia a los paquetes de Identity en _Imports.razor.
Crea una clase de usuario Identity personalizada (ApplicationUser).
Crea y registra un contexto de base de datos EF Core (ApplicationDbContext).
Configura el enrutamiento para los puntos de conexión integrados Identity.
Incluye validación y lógica de negocios de Identity.
Al elegir los modos de representación de WebAssembly interactivo o Automático interactivo, el servidor controla todas las solicitudes de autenticación y autorización, y los componentes de Identity representan estáticamente en el servidor en el proyecto principal de Blazor Web App.
El marco proporciona un AuthenticationStateProvider personalizado en los proyectos de servidor y cliente (.Client) para hacer que fluya el estado de autenticación del usuario al explorador. El proyecto de servidor llama a AddAuthenticationStateSerialization, mientras que el proyecto cliente llama a AddAuthenticationStateDeserialization. La autenticación en el servidor en lugar del cliente permite que la aplicación acceda al estado de autenticación durante la representación previa y antes de que se inicialice el runtime de WebAssembly de .NET. Las implementaciones personalizadas de AuthenticationStateProvider usan el servicio de estado de componente persistente (PersistentComponentState) para serializar el estado de autenticación en comentarios HTML y, después, volverlo a leer desde WebAssembly para crear una instancia de AuthenticationState. Para obtener más información, consulta la sección Configuración del método de Blazor Web App.
Al elegir los modos de representación de WebAssembly interactivo o Automático interactivo, el servidor controla todas las solicitudes de autenticación y autorización, y los componentes de Identity representan estáticamente en el servidor en el proyecto principal de Blazor Web App. La plantilla de proyecto incluye una clase PersistentAuthenticationStateProvider (origen de referencia) en el proyecto .Client para sincronizar el estado de autenticación del usuario entre el servidor y el explorador. La clase es una implementación personalizada de AuthenticationStateProvider. El proveedor usa el servicio de estado de componente persistente (PersistentComponentState) para representar previamente el estado de autenticación y conservarlo en la página.
BlazorIdentity depende de las instancias de DbContext no creadas por una fábrica, lo que es intencional porque DbContext es suficiente para que los componentes de Identity de la plantilla del proyecto se representen estáticamente sin admitir la interactividad.
Para obtener una descripción de cómo se aplican los modos de representación interactiva global a los componentes que no son componentes Identity, mientras que al mismo tiempo se aplica SSR estático a los componentes Identity, consulte ASP.NET Core Blazor modos de representación.
Administrar el estado de la autenticación en Blazor Web App
Esta sección se aplica a Blazor Web App que adoptan:
Cuentas individuales
Representación del lado cliente (CSR, interactividad basada en WebAssembly).
Un proveedor de estado de autenticación del lado cliente solo se usa en Blazor y no está integrado con el sistema de autenticación ASP.NET Core. Durante la representación previa, Blazor respeta los metadatos definidos en la página y usa el sistema de autenticación ASP.NET Core para determinar si el usuario está autenticado. Cuando un usuario navega de una página a otra, se usa un proveedor de autenticación del lado cliente. Cuando el usuario actualiza la página (recarga de página completa), el proveedor de estado de autenticación del lado cliente no participa en la decisión de autenticación en el servidor. Dado que el servidor no conserva el estado del usuario, se pierde ningún estado de autenticación mantenido en el lado cliente.
Para solucionar esto, el mejor enfoque es realizar la autenticación en el sistema de autenticación ASP.NET Core. El proveedor de estado de autenticación del lado cliente solo se encarga de reflejar el estado de autenticación del usuario. Los ejemplos de cómo hacerlo con proveedores de estado de autenticación se muestran mediante la plantilla de proyecto de Blazor Web App y se describen a continuación.
La API solo serializa las notificaciones de rol y nombre del lado servidor para el acceso en el explorador. Para incluir todas las notificaciones, establezca SerializeAllClaims en true en la llamada del lado servidor a AddAuthenticationStateSerialization:
PersistentAuthenticationStateProvider (origen de referencia): para Blazor Web App que adoptan CSR. Se trata de AuthenticationStateProvider del lado del cliente que determina el estado de autenticación del usuario buscando datos persistentes en la página cuando se representó en el servidor. Este estado de autenticación se fija durante la vigencia de CSR. Si el usuario necesita iniciar sesión o cerrar sesión, se requiere una recarga de página completa. Esto solo proporciona un nombre de usuario y un correo electrónico con fines para mostrar. No incluye tokens que se autentican en el servidor al realizar solicitudes posteriores, que se administran por separado mediante un cookie que se incluye en HttpClient solicitudes al servidor.
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.";
}
}
}
Registre el servicio como uno con ámbito. En una aplicación del lado servidor de Blazor, los servicios con ámbito tienen una vigencia igual a la duración del circuito de la conexión de cliente.
En el archivo Program:
builder.Services.AddScoped<ExampleService>();
En Startup.ConfigureServices de Startup.cs:
services.AddScoped<ExampleService>();
En el componente InjectAuthStateProvider siguiente:
El ExampleService se resuelve con OwningComponentBase.ScopedServices y GetRequiredService, que devuelven la instancia correcta e inicializada del ExampleService que existe durante la vigencia del circuito del usuario.
Deshabilite la representación previa: indique el modo de representación con el parámetro prerender establecido en false en el componente de nivel más alto de la jerarquía de componentes de la aplicación que no sea un componente raíz.
Nota
No se admite la creación de un componente raíz interactivo, como el componente App. Por lo tanto, el componente App no puede deshabilitar la representación previa directamente.
En el caso de las aplicaciones basadas en la plantilla de proyecto de Blazor Web App, la representación previa se deshabilita normalmente cuando se usa el componente Routes en el componente App (Components/App.razor):
También puede controlar de forma selectiva el modo de representación aplicado a la instancia del componente Routes. Por ejemplo, consulte los modos de representación de ASP.NET Core Blazor.
Autenticar al usuario en el servidor antes de que se inicie la aplicación: para adoptar este enfoque, la aplicación debe responder a la solicitud inicial de un usuario con la página o vista de inicio de sesión basada en Identity y evitar las solicitudes a puntos de conexión Blazor hasta que se autentiquen. Para más información, consulte Creación de una aplicación ASP.NET Core con datos de usuario protegidos por autorización. Después de la autenticación, solo se muestra contenido no autorizado en componentes de Razor creados previamente cuando el usuario no está autorizado para ver el contenido.
Administración de Estados de usuario
A pesar de contener la palabra "state" (estado) en el nombre, AuthenticationStateProvider no se usa para almacenar el estado del usuario general. AuthenticationStateProvider indica únicamente el estado de autenticación del usuario a la aplicación, si ha iniciado sesión en ella y el nombre de usuario con el que ha iniciado sesión.
La autenticación usa la misma autenticación ASP.NET Core Identity que Razor Pages y las aplicaciones MVC. El estado de usuario almacenado en la Identity de ASP.NET Core se dirige a Blazor sin agregar código adicional a la aplicación. Siga las instrucciones de los artículos y tutoriales de la Identity de ASP.NET Core para que las características de Identity surtan efecto en los elementos Blazor de la aplicación.
Administración del estado de autenticación al cerrar sesión
El Blazor del lado servidor conserva el estado de autenticación del usuario durante la vigencia del circuito, incluidas las pestañas del explorador. Para cerrar la sesión proactiva de un usuario en las pestañas del explorador cuando el usuario cierra sesión en una pestaña, debes implementar un elemento RevalidatingServerAuthenticationStateProvider (origen de referencia) con un elemento RevalidationInterval corto.
Duración de la validez de la dirección URL de redireccionamiento temporal
Esta sección es aplicable a Blazor Web App.
Usa la opción RazorComponentsServiceOptions.TemporaryRedirectionUrlValidityDuration para obtener o establecer la vigencia de la validez de la protección de datos de ASP.NET Core para las direcciones URL de redirección temporales emitidas por la representación del lado servidor Blazor. Solo se usan transitoriamente, por lo que la duración debe simplemente ser lo suficientemente larga como para que un cliente reciba la dirección URL y comience la navegación a ella. Sin embargo, también debe ser lo suficientemente larga como para permitir la asimetría del reloj entre servidores. El valor predeterminado es cinco minutos.
En el ejemplo siguiente, el valor se extiende a siete minutos:
En las aplicaciones Blazor del lado cliente, las comprobaciones de autenticación se pueden omitir porque los usuarios pueden modificar todo el código del lado cliente. Lo mismo se aplica a todas las tecnologías de aplicaciones del lado cliente, incluidas las plataformas JavaScript SPA y las aplicaciones nativas para cualquier sistema operativo.
AuthenticationStateProvider es el servicio subyacente utilizado por el componente AuthorizeView y los servicios de autenticación en cascada para obtener el estado de autenticación de un usuario.
@page "/claims-principal-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>ClaimsPrincipal Data</h1>
<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>
<p>@authMessage</p>
@if (claims.Any())
{
<ul>
@foreach (var claim in claims)
{
<li>@claim.Type: @claim.Value</li>
}
</ul>
}
<p>@surname</p>
@code {
private string? authMessage;
private string? surname;
private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();
private async Task GetClaimsPrincipalData()
{
var authState = await AuthenticationStateProvider
.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && 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.";
}
}
}
En el ejemplo anterior:
ClaimsPrincipal.Claims devuelve las notificaciones del usuario (claims) para mostrarlas en la interfaz de usuario.
La línea que obtiene el apellido del usuario (surname) llama a ClaimsPrincipal.FindAll con un predicado para filtrar las notificaciones del usuario.
@page "/claims-principal-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>ClaimsPrincipal Data</h1>
<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>
<p>@authMessage</p>
@if (claims.Any())
{
<ul>
@foreach (var claim in claims)
{
<li>@claim.Type: @claim.Value</li>
}
</ul>
}
<p>@surname</p>
@code {
private string? authMessage;
private string? surname;
private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();
private async Task GetClaimsPrincipalData()
{
var authState = await AuthenticationStateProvider
.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && 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.";
}
}
}
Si user.Identity.IsAuthenticated es true y porque el usuario es ClaimsPrincipal, se pueden enumerar las notificaciones y evaluar la pertenencia a roles.
Exposición del estado de autenticación como un parámetro en cascada
Si se requieren los datos de estado de autenticación para la lógica de procedimiento, como cuando se realiza una acción desencadenada por el usuario, obtenga los datos de estado de autenticación mediante la definición de un parámetro en cascada del tipo Task<AuthenticationState>, como se muestra en el ejemplo siguiente.
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.";
}
}
}
}
Si user.Identity.IsAuthenticated es true, se pueden enumerar las notificaciones y evaluar la pertenencia a roles.
Al crear una aplicación Blazor a partir de una de las plantillas de proyecto de Blazor con la autenticación habilitada, la aplicación incluye los componentes AuthorizeRouteView y CascadingAuthenticationState que se muestran en el ejemplo siguiente. Una aplicación Blazor del lado cliente también incluye los registros de servicio necesarios. Se presenta información adicional en la sección Personalización del contenido no autorizado con el componente Router.
Con la publicación de ASP.NET Core 5.0.1 y para las versiones 5.x adicionales, el componente Router incluye el parámetro PreferExactMatches establecido en @true. Para más información, vea Migración de ASP.NET Core 3.1 a 5.0.
En una aplicación Blazor del lado cliente, agregue servicios de autorización al archivo Program:
builder.Services.AddAuthorizationCore();
En una aplicación Blazor del lado cliente, agregue servicios relativos a opciones y autorización al archivo Program:
En una aplicación Blazor del lado servidor, ya existen servicios para opciones y autorización, por lo que no es necesario adoptar otros pasos.
Autorización
Cuando un usuario está autenticado, se aplican las reglas de autorización para controlar qué puede hacer el usuario.
Por lo general, se concede o deniega el acceso en función de si:
El usuario está autenticado (ha iniciado sesión).
El usuario está en un rol.
El usuario tiene una notificación.
Una directiva se cumple.
Cada uno de estos conceptos tiene su equivalente en una aplicación ASP.NET Core MVC o Razor Pages. Para más información sobre la seguridad de ASP.NET Core, consulte los artículos disponibles en Seguridad e Identity de ASP.NET Core.
Componente de AuthorizeView
El componente AuthorizeView selectivamente muestra el contenido de la interfaz de usuario dependiendo de si el usuario tiene la autorización necesaria. Este enfoque es útil cuando solo necesites mostrar datos del usuario y no es necesario usar la identity del usuario en la lógica de procedimientos.
El componente expone una variable context del tipo AuthenticationState (@context en sintaxis de Razor), que puede utilizar para acceder a la información sobre el usuario que ha iniciado sesión:
También puede proporcionar contenido diferente para mostrar si el usuario no está autorizado con una combinación de los parámetros Authorized y NotAuthorized:
Aunque el AuthorizeView componente controla la visibilidad de los elementos en función del estado de autorización del usuario, no aplica la seguridad en el propio controlador de eventos. En el ejemplo anterior, el HandleClick método solo está asociado a un botón visible para los usuarios autorizados, pero nada impide invocar este método desde otros lugares. Para garantizar la seguridad de nivel de método, implemente lógica de autorización adicional dentro del propio controlador o en la API pertinente.
Los componentes Razor de Blazor Web App nunca muestran contenido <NotAuthorized> cuando se produce un error de autorización del lado servidor durante la representación estática del lado servidor (SSR estática). La canalización ASP.NET Core del lado servidor procesa la autorización en el servidor. Use técnicas del lado servidor para controlar solicitudes no autorizadas. Para obtener más información, vea Modos de representación de ASP.NET CoreBlazor.
Advertencia
El marcado del lado cliente y los métodos asociados a AuthorizeView solo están protegidos de la visualización y la ejecución en la interfaz de usuario representada en aplicaciones Blazor del lado cliente. Para proteger el contenido autorizado y los métodos en Blazor del lado cliente, el contenido suele proporcionarse mediante una llamada API web segura y autorizada a una API de servidor y nunca se almacena en la aplicación. Para obtener más información, consulte Llamada a una API web desde una aplicación de ASP.NET Core Blazor y Otros escenarios de seguridad de Blazor WebAssembly en ASP.NET Core.
El contenido de Authorized y NotAuthorized puede incluir elementos arbitrarios, como otros componentes interactivos.
Las condiciones de autorización, como los roles o directivas que controlan las opciones o el acceso a la interfaz de usuario, se tratan en la sección Autorización.
Si no se especifican las condiciones de la autorización, AuthorizeView usa una directiva predeterminada:
Se autoriza a los usuarios autenticados (con sesión iniciada).
Se desautoriza a los usuarios no autenticados (sin sesión iniciada).
El componente AuthorizeView se puede usar en el componente NavMenu (Shared/NavMenu.razor) para mostrar un componente NavLink (NavLink), pero tenga en cuenta que este enfoque solo quita el elemento de lista de la salida representada. No impide que el usuario navegue hasta el componente. Implemente la autorización por separado en el componente de destino.
Autorización basada en roles y en directivas
El componente AuthorizeView admite la autorización basada en roles o basada en directivas.
Para la autorización basada en roles, utilice el parámetro Roles. En el ejemplo siguiente, el usuario debe tener una notificación de rol para el rol Admin o Superuser:
<AuthorizeView Roles="Admin, Superuser">
<p>You have an 'Admin' or 'Superuser' role claim.</p>
</AuthorizeView>
Para requerir que un usuario tenga notificaciones de rol de Admin y Superuser, anide componentes AuthorizeView:
<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>
El código anterior establece un valor Context para que el componente interno AuthorizeView evite una colisión de contexto AuthenticationState. Se accede al contexto AuthenticationState en el AuthorizeView exterior con el enfoque estándar para acceder al contexto (@context.User). Se accede al contexto en el AuthorizeView interior con el contexto innerContext con nombre (@innerContext.User).
Para la autorización basada en directivas, use el Policy parámetro con un nombre de directiva único:
<AuthorizeView Policy="Over21">
<p>You satisfy the 'Over21' policy.</p>
</AuthorizeView>
En caso de que el usuario deba cumplir una de varias directivas, cree una directiva que confirme que el usuario cumple otras directivas.
En caso de que el usuario deba cumplir varias directivas simultáneamente, adopte cualquiera de los métodos siguientes:
Cree una directiva para AuthorizeView que confirme que el usuario cumple otras directivas.
Anide las directivas en varios componentes AuthorizeView:
<AuthorizeView Policy="Over21">
<AuthorizeView Policy="LivesInCalifornia">
<p>You satisfy the 'Over21' and 'LivesInCalifornia' policies.</p>
</AuthorizeView>
</AuthorizeView>
La autorización basada en notificaciones es un caso especial de autorización basada en directivas. Por ejemplo, puede definir una directiva que requiere que los usuarios tengan una notificación determinada. Para obtener más información, vea Autorización basada en directivas en ASP.NET Core.
Se autoriza a los usuarios autenticados (con sesión iniciada).
Se desautoriza a los usuarios no autenticados (sin sesión iniciada).
Dado que las comparaciones de cadenas de .NET distinguen mayúsculas de minúsculas, los nombres de rol y directiva coincidentes también distinguen mayúsculas de minúsculas. Por ejemplo, Admin (A mayúscula) no se trata como el mismo rol que admin (a minúscula).
Normalmente se usa la notación Pascal para los nombres de rol y directiva (por ejemplo, BillingAdministrator), pero el uso de esta notación no es un requisito estricto. Se permiten diferentes notaciones, como la grafía camel, la grafía kebab y la grafía de serpiente (distintos tipos de uso de mayúsculas y minúsculas y separaciones con guiones). El uso de espacios en nombres de roles y directivas es inusual, pero lo permite el marco. Por ejemplo, billing administrator es un formato inusual de nombre de directiva o rol en aplicaciones de .NET, pero es un nombre de directiva o rol válido.
Contenido que se muestra durante la autenticación asincrónica
Blazor permite que el estado de autenticación se determine asincrónicamente. El escenario principal para este enfoque se encuentra en las aplicaciones Blazor del lado cliente que realizan una solicitud a un punto de conexión externo para la autenticación.
Mientras la autenticación está en curso, AuthorizeView no muestra ningún contenido. Para mostrar el contenido mientras se produce la autenticación, asigne contenido al parámetro Authorizing:
<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>
Este enfoque no se aplica normalmente a las aplicaciones Blazor del lado servidor. Las aplicaciones Blazor del lado servidor conocen el estado de autenticación tan pronto como se establece ese estado. El contenido de Authorizing se puede proporcionar en un componente AuthorizeView de una aplicación, pero nunca se muestra.
@page "/"
@attribute [Authorize]
You can only see this if you're signed in.
Importante
Utilice únicamente [Authorize] en componentes @page a los que se llega a través del enrutador de Blazor. La autorización solo se realiza como un aspecto del enrutamiento y no para los componentes secundarios representados dentro de una página. Para autorizar la presentación de partes concretas dentro de una página, use AuthorizeView en su lugar.
El atributo [Authorize] admite también la autorización basada en roles o basada en directivas. Para la autorización basada en roles, utilice el parámetro Roles:
@page "/"
@attribute [Authorize(Roles = "Admin, Superuser")]
<p>You can only see this if you're in the 'Admin' or 'Superuser' role.</p>
Para la autorización basada en directivas, utilice el parámetro Policy:
@page "/"
@attribute [Authorize(Policy = "Over21")]
<p>You can only see this if you satisfy the 'Over21' policy.</p>
Cuando la AuthorizeRouteView recibe los datos de ruta del recurso, las directivas de autorización tienen acceso RouteData.PageType a y RouteData.RouteValues que permiten que la lógica personalizada tome decisiones de autorización.
En el ejemplo siguiente, se crea una directiva EditUser en AuthorizationOptions para la configuración del servicio de autorización de la aplicación (AddAuthorizationCore) con la lógica siguiente:
Determine si existe un valor de ruta con una clave de id. Si la clave existe, el valor de ruta se almacena en value.
En una variable denominada id, almacene value como una cadena o establezca un valor de cadena vacío (string.Empty).
Si id no es una cadena vacía, aserte que la directiva se cumple (devuelve true) si el valor de la cadena comienza por EMP. De lo contrario, aserte que se produce un error en la directiva (devuelve false).
using Microsoft.AspNetCore.Components;
using System.Linq;
Agregue la directiva:
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;
})
);
El ejemplo anterior es una directiva de autorización sobreimplificada, que simplemente se usa para demostrar el concepto con un ejemplo práctico. Para obtener más información sobre la creación y configuración de directivas de autorización, vea Autorización basada en directivas en ASP.NET Core.
En el componente EditUser siguiente, el recurso en /users/{id}/edit tiene un parámetro de ruta para el identificador del usuario ({id}). El componente usa la directiva de autorización EditUser anterior para determinar si el valor de ruta de id comienza por EMP. Si id comienza por EMP, la directiva se aplica correctamente y se autoriza el acceso al componente. Si id comienza con un valor distinto de EMP o si id es una cadena vacía, se produce un error en la directiva y el componente no se carga.
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; }
}
Personalización del contenido no autorizado con el componente de Router
El componente Router, junto con el componente AuthorizeRouteView, permite que la aplicación especifique el contenido personalizado si:
La autorización asincrónica está en curso, lo que normalmente significa que el proceso de autenticación del usuario está en curso. Se muestra el marcado del elemento <Authorizing>.
Importante
Las características de enrutador Blazor que muestran el contenido <NotAuthorized> y <NotFound> no están operativas durante la representación estática del lado servidor (SSR estático) porque el procesamiento de solicitudes se controla completamente mediante el procesamiento de solicitudes de canalización de middleware de ASP.NET y los componentes Razor no se representan para solicitudes no autorizadas o incorrectas. Use técnicas del lado servidor para controlar solicitudes no autorizadas e incorrectas durante el SSR estático. Para obtener más información, vea Modos de representación de ASP.NET CoreBlazor.
Una aplicación creada a partir de la plantilla de proyecto de Blazor WebAssembly con la autenticación habilitada incluye un componente RedirectToLogin, que se coloca en el contenido <NotAuthorized> del componente Router. Cuando un usuario no está autenticado (context.User.Identity?.IsAuthenticated != true), el componente RedirectToLogin redirige el explorador al punto de conexión authentication/login para la autenticación. El usuario se devuelve a la dirección URL solicitada después de la autenticación con el proveedor de identity.
Lógica de procedimientos
Si se requiere que la aplicación compruebe las reglas de autorización como parte de la lógica de procedimiento, utilice un parámetro en cascada del tipo Task<AuthenticationState> para obtener el ClaimsPrincipal del usuario. Task<AuthenticationState> se puede combinar con otros servicios, como IAuthorizationService, para evaluar las directivas.
En el ejemplo siguiente:
El user.Identity.IsAuthenticated ejecuta código para los usuarios autenticados (con sesión iniciada).
El user.IsInRole("admin") ejecuta código para los usuarios en el rol "Administrador".
El (await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded ejecuta código para los usuarios que satisfacen la directiva "content-editor".
Una aplicación Blazor del lado servidor incluye los espacios de nombres adecuados de forma predeterminada al crearse a partir de la plantilla de proyecto. En una aplicación Blazor del lado cliente, confirme la presencia de los espacios de nombres Microsoft.AspNetCore.Authorization y Microsoft.AspNetCore.Components.Authorization en el componente o en el archivo de la aplicación _Imports.razor:
@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService
<h1>Procedural Logic Example</h1>
<button @onclick="@DoSomething">Do something important</button>
@code {
[CascadingParameter]
private Task<AuthenticationState>? 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)
{
// ...
}
}
}
}
}
@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService
<h1>Procedural Logic Example</h1>
<button @onclick="@DoSomething">Do something important</button>
@code {
[CascadingParameter]
private Task<AuthenticationState>? 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)
{
// ...
}
}
}
}
}
Solucionar problemas
Errores comunes:
La autorización requiere un parámetro en cascada de tipo Task<AuthenticationState>. Considere la posibilidad de usar CascadingAuthenticationState para proporcionarlo.
Se recibe el valor null para authenticationStateTask
Es probable que el proyecto no se haya creado mediante una plantilla de Blazor del lado servidor con la autenticación habilitada.
En .NET 7 o versiones anteriores, encapsule una instancia de <CascadingAuthenticationState> en alguna parte del árbol de la interfaz, por ejemplo, en el enrutador Blazor:
LA PII hace referencia a cualquier información relacionada con una persona física identificada o identificable. Una persona física identificable es aquella que se puede identificar, directa o indirectamente, con cualquiera de las siguientes opciones:
Uso de middleware de encabezados reenviados para retener la información de esquemas HTTPS en servidores proxy y redes internas.
Escenarios y casos de uso adicionales, incluidos la configuración manual de esquemas, los cambios en las rutas de las solicitudes para corregir el enrutamiento de las solicitudes y el reenvío de esquemas de solicitudes para Linux y proxies inversos que no sean de tipo IIS.
Documentación de la plataforma de identity de Microsoft
Uso de middleware de encabezados reenviados para retener la información de esquemas HTTPS en servidores proxy y redes internas.
Escenarios y casos de uso adicionales, incluidos la configuración manual de esquemas, los cambios en las rutas de las solicitudes para corregir el enrutamiento de las solicitudes y el reenvío de esquemas de solicitudes para Linux y proxies inversos que no sean de tipo IIS.
Documentación de la plataforma de identity de Microsoft
El origen de este contenido se puede encontrar en GitHub, donde también puede crear y revisar problemas y solicitudes de incorporación de cambios. Para más información, consulte nuestra guía para colaboradores.
Comentarios de ASP.NET Core
ASP.NET Core es un proyecto de código abierto. Selecciona un vínculo para proporcionar comentarios:
Muestre las características de Microsoft Entra ID para modernizar las soluciones de identidad, implementar soluciones híbridas e implementar la gobernanza de identidades.