Compartir vía


Estado de autenticació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, 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 crear un proveedor de estado de autenticación personalizado y recibir notificaciones de cambio de estado de autenticación de usuario en código.

Los enfoques generales que se toman para las aplicaciones Blazor del lado servidor y del lado cliente son similares, pero difieren en sus implementaciones exactas, por lo que este artículo cambia entre aplicaciones Blazor del lado servidor y aplicaciones Blazor del lado cliente. Usa el selector de dinámica de la parte superior del artículo para cambiar el artículo para que coincida con el tipo de proyecto Blazor con el que estás trabajando:

  • Aplicaciones Blazor del lado servidor (dinámica Server): Blazor Server para .NET 7 o versiones anteriores y el proyecto de servidor de Blazor Web App para .NET 8 o posterior.
  • Aplicaciones Blazor del lado cliente (dinámica Blazor WebAssembly): Blazor WebAssembly para todas las versiones de .NET o el proyecto .Client de Blazor Web App para .NET 8 o posterior.

Clase AuthenticationStateProvider abstracta

El marco Blazor incluye una clase AuthenticationStateProvider abstracta para proporcionar información sobre el estado de autenticación del usuario actual con los miembros siguientes:

Implementación de un elemento AuthenticationStateProvider personalizado

La aplicación debe hacer referencia al paquete NuGet Microsoft.AspNetCore.Components.Authorization, que proporciona compatibilidad de autenticación y autorización para aplicaciones Blazor.

Nota:

Para obtener instrucciones sobre cómo agregar paquetes a aplicaciones .NET, consulta los artículos de Instalación y administración de paquetes en Flujo de trabajo de consumo de paquetes (documentación de NuGet). Confirma las versiones correctas del paquete en NuGet.org.

Configura los siguientes servicios de autenticación, autorización y estado de autenticación en cascada en el archivo Program.

Al crear una aplicación Blazor a partir de una de las plantillas de proyecto Blazor con autenticación habilitada, la aplicación está preconfigurada con los siguientes registros de servicio, que incluye exponer el estado de autenticación como un parámetro en cascada. Para obtener más información, consulta Autenticación y autorización de ASP.NET Core Blazor con información adicional presentada en la sección Personalización de contenido no autorizado con el componente Router del artículo.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorization();
builder.Services.AddCascadingAuthenticationState();

Configura los servicios de autenticación y autorización en el archivo Program.

Al crear una aplicación Blazor a partir de una de las plantillas de proyecto Blazor con la autenticación habilitada, la aplicación incluye el siguiente registro de servicio.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorization();

Configura los servicios de autenticación y autorización en Startup.ConfigureServices de Startup.cs.

Al crear una aplicación Blazor a partir de una de las plantillas de proyecto Blazor con la autenticación habilitada, la aplicación incluye el siguiente registro de servicio.

using Microsoft.AspNetCore.Components.Authorization;

...

services.AddAuthorization();

En aplicaciones Blazor WebAssembly (todas las versiones de .NET) o en el proyecto .Client de Blazor Web App (.NET 8 o posterior), configura los servicios de autenticación, autorización y estado de autenticación en cascada en el archivo Program.

Al crear una aplicación Blazor a partir de una de las plantillas de proyecto Blazor con autenticación habilitada, la aplicación está preconfigurada con los siguientes registros de servicio, que incluye exponer el estado de autenticación como un parámetro en cascada. Para obtener más información, consulta Autenticación y autorización de ASP.NET Core Blazor con información adicional presentada en la sección Personalización de contenido no autorizado con el componente Router del artículo.

using Microsoft.AspNetCore.Components.Authorization;

...

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

Configura los servicios de autenticación y autorización en el archivo Program.

Al crear una aplicación Blazor a partir de una de las plantillas de proyecto Blazor con la autenticación habilitada, la aplicación incluye el siguiente registro de servicio.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorizationCore();

Subclase AuthenticationStateProvider e invalidación GetAuthenticationStateAsync para crear el estado de autenticación del usuario. En el siguiente ejemplo, todos los usuarios se autentican con el nombre de usuario mrfibuli.

CustomAuthStateProvider.cs:

using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var identity = new ClaimsIdentity(
        [
            new Claim(ClaimTypes.Name, "mrfibuli"),
        ], "Custom Authentication");

        var user = new ClaimsPrincipal(identity);

        return Task.FromResult(new AuthenticationState(user));
    }
}

Nota:

El código anterior que crea un nuevo ClaimsIdentity usa la inicialización simplificada de la colección introducida con C# 12 (.NET 8). Para obtener más información, consulta Expresiones de colección: Referencia del lenguaje C#.

El servicio CustomAuthStateProvider se registra en el archivo Program: Registra los servicios con ámbito con AddScoped:

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

En una aplicación Blazor Server, registra el servicio con ámbito con AddScopeddespués de la llamada a AddServerSideBlazor:

builder.Services.AddServerSideBlazor();

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

En una aplicación Blazor Server, registra el servicio con ámbito con AddScopeddespués de la llamada a AddServerSideBlazor:

services.AddServerSideBlazor();

services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

El servicio CustomAuthStateProvider se registra en el archivo Program: Registra el singleton de servicio con AddSingleton:

builder.Services.AddSingleton<AuthenticationStateProvider, CustomAuthStateProvider>();

Si no está presente, agrega una instrucción @using al archivo _Imports.razor para que el espacio de nombres Microsoft.AspNetCore.Components.Authorization esté disponible en los componentes:

@using Microsoft.AspNetCore.Components.Authorization;

Confirma o cambia el componente de vista de ruta a una AuthorizeRouteView en la definición del componente Router. La ubicación del componente Router difiere en función del tipo de aplicación. Usa la búsqueda para localizar el componente si no eres consciente de su ubicación en el proyecto.

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

Nota:

Al crear una aplicación de Blazor a partir de una de las plantillas de proyecto de Blazor con la autenticación habilitada, la aplicación incluye el componente AuthorizeRouteView. Para obtener más información, consulta Autenticación y autorización de ASP.NET Core Blazor con información adicional presentada en la sección Personalización de contenido no autorizado con el componente Router del artículo.

Donde se encuentra el componente Router:

La ubicación del componente Router difiere en función del tipo de aplicación. Usa la búsqueda para localizar el componente si no eres consciente de su ubicación en el proyecto.

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

Nota:

Al crear una aplicación de Blazor a partir de una de las plantillas de proyecto de Blazor con la autenticación habilitada, la aplicación incluye el componente AuthorizeRouteView y los componentes CascadingAuthenticationState. Para obtener más información, consulta Autenticación y autorización de ASP.NET Core Blazor con información adicional presentada en la sección Personalización de contenido no autorizado con el componente Router del artículo.

En el siguiente componente AuthorizeView de ejemplo se muestra el nombre del usuario autenticado:

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

Para obtener instrucciones sobre el uso de la AuthorizeView, consulte Autenticación y autorización de Blazor en ASP.NET Core.

Notificaciones de cambio de estado de autenticación

Un AuthenticationStateProvider personalizado puede invocar a NotifyAuthenticationStateChanged en la clase base del AuthenticationStateProvider para notificar a los consumidores del cambio de estado de la autenticación para una nueva representación.

El ejemplo siguiente se basa en la implementación de un AuthenticationStateProvider personalizado mediante el seguimiento de las instrucciones de la sección Implementar un AuthenticationStateProvider personalizado anteriormente en este artículo. Si ya has seguido las instrucciones de esa sección, el siguiente CustomAuthStateProvider reemplaza al que se muestra en la sección.

La siguiente implementación del CustomAuthStateProvider expone un método personalizado, AuthenticateUser, para iniciar sesión con un usuario y notificar a los consumidores del cambio de estado de la autenticación.

CustomAuthStateProvider.cs:

using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var identity = new ClaimsIdentity();
        var user = new ClaimsPrincipal(identity);

        return Task.FromResult(new AuthenticationState(user));
    }

    public void AuthenticateUser(string userIdentifier)
    {
        var identity = new ClaimsIdentity(
        [
            new Claim(ClaimTypes.Name, userIdentifier),
        ], "Custom Authentication");

        var user = new ClaimsPrincipal(identity);

        NotifyAuthenticationStateChanged(
            Task.FromResult(new AuthenticationState(user)));
    }
}

Nota:

El código anterior que crea un nuevo ClaimsIdentity usa la inicialización simplificada de la colección introducida con C# 12 (.NET 8). Para obtener más información, consulta Expresiones de colección: Referencia del lenguaje C#.

En un componente:

@inject AuthenticationStateProvider AuthenticationStateProvider

<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    public string userIdentifier = string.Empty;

    private void SignIn()
    {
        ((CustomAuthStateProvider)AuthenticationStateProvider)
            .AuthenticateUser(userIdentifier);
    }
}

El enfoque anterior se puede mejorar para desencadenar notificaciones de cambios de estado de autenticación a través de un servicio personalizado. La siguiente clase CustomAuthenticationService mantiene la entidad de seguridad de notificaciones del usuario actual en un campo de respaldo (currentUser) con un evento (UserChanged) al que se puede suscribir el proveedor de estado de autenticación, donde el evento invoca a NotifyAuthenticationStateChanged. Con la configuración adicional que se verá más adelante en esta sección, CustomAuthenticationService se puede insertar en un componente con lógica que establece al CurrentUser para desencadenar el evento UserChanged.

CustomAuthenticationService.cs:

using System.Security.Claims;

public class CustomAuthenticationService
{
    public event Action<ClaimsPrincipal>? UserChanged;
    private ClaimsPrincipal? currentUser;

    public ClaimsPrincipal CurrentUser
    {
        get { return currentUser ?? new(); }
        set
        {
            currentUser = value;

            if (UserChanged is not null)
            {
                UserChanged(currentUser);
            }
        }
    }
}

En el archivo Program, registre el CustomAuthenticationService en el contenedor de inserción de dependencias:

builder.Services.AddScoped<CustomAuthenticationService>();

En los Startup.ConfigureServices de Startup.cs, registre el CustomAuthenticationService en el contenedor de inserción de dependencias:

services.AddScoped<CustomAuthenticationService>();

En el archivo Program, registre el CustomAuthenticationService en el contenedor de inserción de dependencias:

builder.Services.AddSingleton<CustomAuthenticationService>();

El siguiente CustomAuthStateProvider se suscribe al evento CustomAuthenticationService.UserChanged. El método GetAuthenticationStateAsync devuelve el estado de autenticación del usuario. Inicialmente, el estado de autenticación se basa en el valor de CustomAuthenticationService.CurrentUser. Cuando el usuario cambia, se crea un nuevo estado de autenticación para el nuevo usuario (new AuthenticationState(newUser)) para las llamadas a GetAuthenticationStateAsync:

using Microsoft.AspNetCore.Components.Authorization;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    private AuthenticationState authenticationState;

    public CustomAuthStateProvider(CustomAuthenticationService service)
    {
        authenticationState = new AuthenticationState(service.CurrentUser);

        service.UserChanged += (newUser) =>
        {
            authenticationState = new AuthenticationState(newUser);
            NotifyAuthenticationStateChanged(Task.FromResult(authenticationState));
        };
    }

    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        Task.FromResult(authenticationState);
}

El método de SignIn del componente siguiente crea una entidad de seguridad de notificaciones para que el identificador del usuario lo establezca en el CustomAuthenticationService.CurrentUser:

@using System.Security.Claims
@inject CustomAuthenticationService AuthService

<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    public string userIdentifier = string.Empty;

    private void SignIn()
    {
        var currentUser = AuthService.CurrentUser;

        var identity = new ClaimsIdentity(
            [
                new Claim(ClaimTypes.Name, userIdentifier),
            ],
            "Custom Authentication");

        var newUser = new ClaimsPrincipal(identity);

        AuthService.CurrentUser = newUser;
    }
}

Nota:

El código anterior que crea un nuevo ClaimsIdentity usa la inicialización simplificada de la colección introducida con C# 12 (.NET 8). Para obtener más información, consulta Expresiones de colección: Referencia del lenguaje C#.

Recursos adicionales