Protección de aplicaciones de Blazor del lado servidor de ASP.NET Core
Nota:
Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 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 .NET 8 de este artículo.
En este artículo se explica cómo proteger las aplicaciones de Blazor del lado servidor como aplicaciones ASP.NET Core.
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, es decir, cuando la aplicación se conecta por primera vez a WebSocket. 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 escenarios de seguridad adicionales del lado servidor de ASP.NET Core Blazor.
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.
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 Identity del marco Blazor, 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.
Para obtener más información sobre la interfaz de usuario de identidad de BlazorIdentity y orientación sobre cómo integrar inicios de sesión externos a través de sitios web sociales, consulta Novedades de la identity en .NET 8.
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 archivoProgram
del proyecto del cliente (.Client
), 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();
PersistingRevalidatingAuthenticationStateProvider
(origen de referencia): para Blazor Web App que adoptan la representación interactiva del lado servidor (SSR interactivo) y la representación del lado cliente (CSR). Se trata de un AuthenticationStateProvider del lado servidor que vuelve a validar la marca de seguridad para el usuario conectado cada 30 minutos, se conecta un circuito interactivo. También utiliza el servicio de estado de componente persistente para transmitir el estado de autenticación al cliente, que luego se fija durante la vida útil de CSR.PersistingServerAuthenticationStateProvider
(origen de referencia): para Blazor Web App que solo adoptan CSR. Se trata de un AuthenticationStateProvider del lado del servidor que utiliza el servicio de estado de componente persistente para transmitir el estado de autenticación al cliente, que luego se fija durante la vida útil de CSR.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 enHttpClient
solicitudes al servidor.
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, vea 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:
- El componente hereda OwningComponentBase.
- El AuthenticationStateProvider se inserta y se pasa al
ExampleService.ExampleMethod
. - El
ExampleService
se resuelve con OwningComponentBase.ScopedServices y GetRequiredService, que devuelven la instancia correcta e inicializada delExampleService
que existe durante la vigencia del circuito del usuario.
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 AuthenticationStateProvider
personalizado
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:
Implemente IHostEnvironmentAuthenticationStateProvider para el AuthenticationStateProvider personalizado para admitir la representación previa: para obtener un ejemplo de implementación de IHostEnvironmentAuthenticationStateProvider, consulte la implementación ServerAuthenticationStateProvider del marco Blazor en
ServerAuthenticationStateProvider.cs
(origen de referencia).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, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Deshabilite la representación previa: indique el modo de representación con el parámetro
prerender
establecido enfalse
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 componenteApp
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 componenteApp
(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.
Deshabilitar la representación previa: abra el archivo
_Host.cshtml
y cambie el atributorender-mode
del asistente de etiquetas de componente a Server:<component type="typeof(App)" render-mode="Server" />
- 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:
ServerAuthenticationStateProvider (origen de referencia): AuthenticationStateProvider que usa el marco de Blazor para obtener el estado de autenticación del servidor.
RevalidatingServerAuthenticationStateProvider (origen de referencia): clase base para servicios de AuthenticationStateProvider usados por el marco de Blazor para recibir un estado de autenticación del entorno del host y volver a validarlo a intervalos regulares.
El intervalo de revalidación predeterminado de 30 minutos se puede ajustar en
RevalidatingIdentityAuthenticationStateProvider
(Areas/Identity/RevalidatingIdentityAuthenticationStateProvider.cs
). En el ejemplo siguiente se reduce el intervalo a 20 minutos:protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(20);
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, vea 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));
Recursos adicionales
- Inicio rápido: Adición del inicio de sesión con Microsoft en una aplicación web de ASP.NET Core
- Inicio rápido: Protección de una API web de ASP.NET Core con la plataforma de identity de Microsoft
- Configuración de ASP.NET Core para trabajar con servidores proxy y equilibradores de carga: incluye instrucciones para:
- 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.