Compartir a través de


Autenticación y autorización de ASP.NET Core Blazor

Nota

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 9 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la directiva de compatibilidad de .NET y .NET Core. Para la versión actual, consulte la versión de .NET 9 de este artículo.

Importante

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í.

Para la versión actual, consulte la versión de .NET 9 de este artículo.

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.

Las convenciones de autorización de Razor Pages no se aplican a los componentes de Razor enrutables. Si se inserta un componente de Razor no enrutable en una página de una aplicación de páginas de Razor, las convenciones de autorización de la página afectan indirectamente al componente de Razor y al rest del contenido de la página.

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.

Las abstracciones de ASP.NET Core, como SignInManager<TUser> y UserManager<TUser>, no se admiten en los componentes Razor. Para más información sobre el uso de Identity de ASP.NET Core con Blazor, vea Scaffolding de Identity de ASP.NET Core en una aplicación Blazor del lado servidor.

Nota

En los ejemplos de código de este artículo se adoptan tipos de referencia que admiten un valor NULL (NRT) y análisis estático de estado NULL del compilador de .NET, que se admiten en ASP.NET Core en .NET 6 o posterior. Al tener como destino ASP.NET Core 5.0 o versiones anteriores, quite la designación de tipo null (?) de los ejemplos del artículo.

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:

Compatibilidad con antiforgería

La plantilla Blazor:

El componente AntiforgeryToken representa un token de antifalsificación como un campo oculto y este componente se agrega automáticamente a las instancias de formulario (EditForm). Para obtener más información, vea Introducción a los formularios de ASP.NET CoreBlazor.

El servicio AntiforgeryStateProvider proporciona acceso a un token de antifalsificación asociado a la sesión actual. Inserte el servicio y llame a su método GetAntiforgeryToken() para obtener el valor AntiforgeryRequestTokenactual. Para obtener más información, vea Llamada a una API web desde una aplicación Blazor de ASP.NET Core.

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.

Nota

La mitigación antiforgería solo es necesaria al enviar datos de formulario al servidor codificados como application/x-www-form-urlencoded, multipart/form-data, o text/plain, ya que son los únicos tipos de formulario válidos.

Para obtener más información, consulte los siguientes recursos:

Autenticación de Blazor del lado servidor

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.

Nota

En los ejemplos de código de este artículo se adoptan tipos de referencia que admiten un valor NULL (NRT) y análisis estático de estado NULL del compilador de .NET, que se admiten en ASP.NET Core en .NET 6 o posterior. Al tener como destino ASP.NET Core 5.0 o versiones anteriores, quite la designación de tipo null (?) de los ejemplos del artículo.

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.

Para obtener instrucciones generales sobre la administración de estados, consulte: Administración de estados de Blazor en ASP.NET Core.

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.

Plantilla de proyectos

Cree una nueva aplicación de Blazor del lado servidor siguiendo las instrucciones de Herramienta para ASP.NET Core Blazor.

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.
  • Plataforma de identity de Microsoft: para más información, consulta Autenticación y autorización de ASP.NET Core Blazor.
  • Windows: use la autenticación de Windows.

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.

Para inspeccionar los componentes Blazor del marco Identity, accede a ellos en las carpetas Pages y Shared de la carpeta Account de la plantilla de proyecto Blazor Web App (origen de referencia).

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.

Solo para las soluciones de Servidor interactivo, IdentityRevalidatingAuthenticationStateProvider (origen de referencia) es un AuthenticationStateProvider de lado servidor que vuelve a validar la marca de seguridad para el usuario conectado cada 30 minutos que se conecta un circuito interactivo.

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.

En el proyecto principal de Blazor Web App, el proveedor de estado de autenticación se denomina IdentityRevalidatingAuthenticationStateProvider (origen de referencia) (solo soluciones de interactividad de servidor) o PersistingRevalidatingAuthenticationStateProvider (origen de referencia) (Soluciones de interactividad de WebAssembly o Auto interactividad).

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.

Para obtener más información sobre cómo conservar el estado prerrepresentado, consulte Prerrepresentar componentes Razor ASP.NET Core.

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, consulta Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

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.

En el archivo Program del proyecto de servidor, llame a AddAuthenticationStateSerialization, que serializa la AuthenticationState devuelta por el AuthenticationStateProvider del lado servidor mediante el servicio estado de componente persistente (PersistentComponentState):

builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents()
    .AddAuthenticationStateSerialization();

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:

builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents()
    .AddAuthenticationStateSerialization(
        options => options.SerializeAllClaims = true);

En el archivo.Client del proyecto del cliente (Program), llame a AddAuthenticationStateDeserialization, que agrega un AuthenticationStateProvider en el que el AuthenticationState se deserializa desde el servidor mediante AuthenticationStateData y el servicio de estado de componente persistente (PersistentComponentState). Debe haber una llamada correspondiente a AddAuthenticationStateSerialization en el proyecto de servidor.

builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, consulta Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Scaffolding para Identity

Para obtener más información sobre scaffolding de Identity en un proyecto de aplicación Blazor del lado servidor, consulte Scaffolding de Identity en proyectos de ASP.NET Core.

Scaffolding de Identity a una aplicación de Blazor del lado servidor:

Notificaciones y tokens adicionales de proveedores externos

Para almacenar notificaciones adicionales de proveedores externos, consulte Conservar notificaciones y tokens adicionales en in ASP.NET Core.

Azure App Service en Linux con Identity Server

Al realizar una implementación en Azure App Service en Linux con Identity Server, especifique el emisor de forma explícita. Para más información, consulte Uso de Identity para proteger un back-end de API web para SPA.

Inserción del AuthenticationStateProvider para los servicios con ámbito en un componente

No intente resolver AuthenticationStateProvider dentro de un ámbito personalizado porque dará como resultado la creación de una nueva instancia del AuthenticationStateProvider que no se inicializa correctamente.

Para acceder al AuthenticationStateProvider dentro de un servicio con ámbito en un componente, inserte al AuthenticationStateProvider con la directiva @inject o el atributo [Inject] y páselo al servicio como parámetro. Este enfoque garantiza que la instancia correcta e inicializada del AuthenticationStateProvider se use para cada instancia de aplicación de usuario.

ExampleService.cs:

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:

InjectAuthStateProvider.razor:

@page "/inject-auth-state-provider"
@inherits OwningComponentBase
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>

<p>@message</p>

@code {
    private string? message;
    private ExampleService? ExampleService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        ExampleService = ScopedServices.GetRequiredService<ExampleService>();

        message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
    }
}
@page "/inject-auth-state-provider"
@inject AuthenticationStateProvider AuthenticationStateProvider
@inherits OwningComponentBase

<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>

<p>@message</p>

@code {
    private string? message;
    private ExampleService? ExampleService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        ExampleService = ScopedServices.GetRequiredService<ExampleService>();

        message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
    }
}

Para más información, consulte las instrucciones de OwningComponentBase en la Inserción de dependencias de Blazor en ASP.NET Core.

Presentación de contenido no autorizado durante la representación previa con un AuthenticationStateProviderpersonalizado

Para evitar mostrar contenido no autorizado, por ejemplo contenido en un componente AuthorizeView, mientras se representa previamente con un elemento AuthenticationStateProvider personalizado, adopte uno de los enfoques siguientes:

  • 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):

    <Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    

    Además, deshabilite la representación previa para el componente de HeadOutlet:

    <HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    

    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.

Para obtener instrucciones sobre la administración de estado general fuera de la Identity de ASP.NET Core, consulte: Administración de estado de Blazor en ASP.NET Core.

Abstracciones de seguridad adicionales

Dos abstracciones adicionales participan en la administración del estado de autenticación:

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, consulta Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

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.

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, consulta Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

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:

builder.Services.AddRazorComponents(options => 
    options.TemporaryRedirectionUrlValidityDuration = 
        TimeSpan.FromMinutes(7));

Autenticación de Blazor del lado cliente

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.

Agregue la siguiente línea de código:

Para controlar la autenticación, usa el servicio AuthenticationStateProvider integrado o personalizado.

Para obtener más información sobre la autenticación del lado cliente, consulta Secure ASP.NET Core Blazor WebAssembly.

Servicio AuthenticationStateProvider

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.

AuthenticationStateProvider es el servicio subyacente utilizado por el componente AuthorizeView y el componente CascadingAuthenticationState para obtener el estado de autenticación de un usuario.

Por lo general, no se utiliza AuthenticationStateProvider directamente. Use los enfoques del componente AuthorizeView o Task<AuthenticationState> descritos más adelante en este artículo. El principal inconveniente de utilizar AuthenticationStateProvider directamente es que el componente no se notifica de manera automática si cambia el estado de autenticación subyacente de los datos.

Para implementar un AuthenticationStateProvider personalizado, consulta ASP.NET Core Blazorestado de autenticación, que incluye una guía sobre la implementación de notificaciones de cambio de estado de autenticación de usuario.

Obtención de los datos de entidad de seguridad de notificaciones de un usuario

El servicio AuthenticationStateProvider puede proporcionar los datos de ClaimsPrincipal del usuario actual, como se muestra en el ejemplo siguiente.

ClaimsPrincipalData.razor:

@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.

Para más información sobre la inserción de dependencias (DI) y servicios, consulte Inserción de dependencias de Blazor de ASP.NET Core y Inserción de dependencias en ASP.NET Core. Para obtener información sobre cómo implementar un AuthenticationStateProvider personalizado, consulta ASP.NET Core Blazor estado de autenticación.

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.

Configure el Task<AuthenticationState> y utilice para ello AuthorizeRouteView y los servicios de estado de autenticación en cascada.

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 la llamada a AuthorizeRouteView y AddCascadingAuthenticationState 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.

<Router ...>
    <Found ...>
        <AuthorizeRouteView RouteData="routeData" 
            DefaultLayout="typeof(Layout.MainLayout)" />
        ...
    </Found>
</Router>

En el archivo Program, registre los servicios de estado de autenticación en cascada:

builder.Services.AddCascadingAuthenticationState();

Configure el Task<AuthenticationState> y utilice para ello los componentes AuthorizeRouteView y CascadingAuthenticationState.

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.

<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView RouteData="routeData" 
                DefaultLayout="typeof(MainLayout)" />
            ...
        </Found>
    </Router>
</CascadingAuthenticationState>

Nota

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:

builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();

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:

<AuthorizeView>
    <p>Hello, @context.User.Identity?.Name!</p>
</AuthorizeView>

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:

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
        <p><button @onclick="HandleClick">Authorized Only Button</button></p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    private void HandleClick() { ... }
}

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 más información, además de una guía de configuración, consulte Autorización basada en roles en ASP.NET Core.

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.

Si no se especifica Roles ni Policy, AuthorizeView usa la directiva predeterminada:

  • 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.

Atributo [Authorize]

El atributo [Authorize] está disponible en los componentes Razor:

@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>

Si no se especifica Roles ni Policy, [Authorize] usa la directiva predeterminada:

  • Se autoriza a los usuarios autenticados (con sesión iniciada).
  • Se desautoriza a los usuarios no autenticados (sin sesión iniciada).

Cuando el usuario no está autorizado y si la aplicación no personaliza contenido no autorizado con el componente de Router, el marco muestra automáticamente el siguiente mensaje de reserva:

Not authorized.

Autorización de recursos

Para autorizar a los usuarios para los recursos, pase los datos de ruta de la solicitud al parámetro Resource de AuthorizeRouteView.

En el contenido de Router.Found de una ruta solicitada:

<AuthorizeRouteView Resource="routeData" RouteData="routeData" 
    DefaultLayout="typeof(MainLayout)" />

Para obtener más información sobre cómo se pasan los datos de estado de autorización y cómo se usan en la lógica de procedimientos, consulte la sección Exposición del estado de autenticación como parámetro en cascada.

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).

En el archivo Program:

  • Agregue espacios de nombres de Microsoft.AspNetCore.Components y System.Linq:

    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:

  • El usuario produce un error en la condición [Authorize] aplicada al componente. Se muestra el marcado del elemento <NotAuthorized>. El atributo [Authorize] se describe en la sección Atributo [Authorize].
  • 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.

<Router ...>
    <Found ...>
        <AuthorizeRouteView ...>
            <NotAuthorized>
                ...
            </NotAuthorized>
            <Authorizing>
                ...
            </Authorizing>
        </AuthorizeRouteView>
    </Found>
</Router>

El contenido de Authorized y NotAuthorized puede incluir elementos arbitrarios, como otros componentes interactivos.

Nota

El anterior requiere el registro de servicios de estado de autenticación en cascada en el archivo Program de la aplicación:

builder.Services.AddCascadingAuthenticationState();
<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView ...>
                <NotAuthorized>
                    ...
                </NotAuthorized>
                <Authorizing>
                    ...
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
    </Router>
</CascadingAuthenticationState>

El contenido de NotFound, Authorized y NotAuthorized puede incluir elementos arbitrarios, como otros componentes interactivos.

Si no se especifica el contenido NotAuthorized, el AuthorizeRouteView usa el siguiente mensaje de reserva:

Not authorized.

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:

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization

ProceduralLogic.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:

<CascadingAuthenticationState>
    <Router ...>
        ...
    </Router>
</CascadingAuthenticationState>

En .NET 8 o versiones posteriores, no use el componente CascadingAuthenticationState:

- <CascadingAuthenticationState>
      <Router ...>
          ...
      </Router>
- </CascadingAuthenticationState>

En su lugar, agregue servicios de estado de autenticación en cascada a la colección de servicios del archivo Program:

builder.Services.AddCascadingAuthenticationState();

El componente CascadingAuthenticationState (.NET 7 o versiones anteriores) o los servicios proporcionados por AddCascadingAuthenticationState (.NET 8 o versiones posterior) proporcionan el parámetro Task<AuthenticationState> en cascada, que a su vez recibe del servicio de inserción AuthenticationStateProvider de dependencias subyacente.

Información de identificación personal

Microsoft usa la definición del RGPD para "datos personales" (RGPD 4.1) cuando la documentación describe información de identificación personal (PII).

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:

  • Nombre
  • Número de identificación
  • Coordenadas de ubicación
  • Identificador en línea
  • Otros factores específicos
    • Físico
    • Fisiológica
    • Genética
    • Mental (psicológico)
    • Económico
    • Cultural
    • identity social

Recursos adicionales