Compartilhar via


Estado de autenticação do ASP.NET Core Blazor

Observação

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.

Aviso

Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.

Importante

Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Para a versão atual, consulte a versão .NET 9 deste artigo.

Este artigo explica como criar um provedor de estado de autenticação personalizado e receber notificações de alteração de estado de autenticação do usuário no código.

As abordagens gerais adotadas para aplicativos do Blazor do lado do servidor e do lado do cliente são semelhantes, mas diferem em suas implementações exatas, portanto, este artigo alterna entre aplicativos do Blazor do lado do servidor e aplicativos do Blazor do lado do cliente. Use o seletor do pivô na parte superior do artigo para alterar o pivô do artigo para corresponder ao tipo de projeto do Blazor com o qual você está trabalhando:

  • Aplicativos do Blazor do lado do servidor (pivô Server): Blazor Server para .NET 7 ou anterior e o projeto de servidor de um Blazor Web App para .NET 8 ou posterior.
  • Aplicativos do Blazor do lado do cliente (pivô Blazor WebAssembly): Blazor WebAssembly para todas as versões do .NET ou o projeto .Client de um Blazor Web App para .NET 8 ou posterior.

Classe AuthenticationStateProvider abstrata

A estrutura Blazor inclui uma classe AuthenticationStateProvider abstrata para fornecer informações sobre o estado de autenticação do usuário atual com os seguintes membros:

Implementar um AuthenticationStateProvider personalizado

O aplicativo deve fazer referência ao pacote NuGet Microsoft.AspNetCore.Components.Authorization, que fornece suporte de autenticação e autorização para aplicativos do Blazor.

Observação

Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes no Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.

Configure os seguintes serviços de estado de autenticação, autorização e autenticação em cascata no arquivo Program.

Quando você cria um aplicativo do Blazor de um dos modelos de projeto do Blazor com autenticação habilitada, o aplicativo é pré-configurado com os seguintes registros de serviço, o que inclui expor o estado de autenticação como um parâmetro em cascata. Para mais informações, consulte Autenticação e autorização do ASP.NET Core Blazor com informações adicionais apresentadas na seção Personalizar conteúdo não autorizado com o componente Router.

using Microsoft.AspNetCore.Components.Authorization;

...

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

Configure os serviços de autenticação e autorização no arquivo Program.

Quando você cria um aplicativo do Blazor de um dos modelos de projeto do Blazor com a autenticação habilitada, o aplicativo inclui o seguinte registro de serviço:

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorization();

Configurar serviços de autenticação e autorização em Startup.ConfigureServices de Startup.cs.

Quando você cria um aplicativo do Blazor de um dos modelos de projeto do Blazor com a autenticação habilitada, o aplicativo inclui o seguinte registro de serviço:

using Microsoft.AspNetCore.Components.Authorization;

...

services.AddAuthorization();

Em aplicativos do Blazor WebAssembly (todas as versões do .NET) ou do projeto do .Client de um Blazor Web App (.NET 8 ou posterior), configure os serviços de estado de autenticação, autorização e autenticação em cascata no arquivo Program.

Quando você cria um aplicativo do Blazor de um dos modelos de projeto do Blazor com autenticação habilitada, o aplicativo é pré-configurado com os seguintes registros de serviço, o que inclui expor o estado de autenticação como um parâmetro em cascata. Para mais informações, consulte Autenticação e autorização do ASP.NET Core Blazor com informações adicionais apresentadas na seção Personalizar conteúdo não autorizado com o componente Router.

using Microsoft.AspNetCore.Components.Authorization;

...

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

Configure os serviços de autenticação e autorização no arquivo Program.

Quando você cria um aplicativo do Blazor de um dos modelos de projeto do Blazor com a autenticação habilitada, o aplicativo inclui o seguinte registro de serviço:

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorizationCore();

Subclasse AuthenticationStateProvider e substituição GetAuthenticationStateAsync para criar o estado de autenticação do usuário. No exemplo a seguir, todos os usuários são autenticados com o nome de usuário 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));
    }
}

Observação

O código anterior que cria um novo ClaimsIdentity usa a inicialização de coleção simplificada introduzida com o C# 12 (.NET 8). Para mais informações, consulte Expressões de coleção – Referência da linguagem C#.

O serviço CustomAuthStateProvider é registrado no arquivo Program. Registreo serviço com escopo com AddScoped.

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

Em um aplicativo do Blazor Server, registre o serviço com escopo com AddScopedapós a chamada para AddServerSideBlazor:

builder.Services.AddServerSideBlazor();

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

Em um aplicativo do Blazor Server, registre o serviço com escopo com AddScopedapós a chamada para AddServerSideBlazor:

services.AddServerSideBlazor();

services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

O serviço CustomAuthStateProvider é registrado no arquivo Program. Registre o singleton de serviço com AddSingleton:

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

Se ele não estiver presente, adicione uma instrução @using ao arquivo _Imports.razor para disponibilizar o namespace Microsoft.AspNetCore.Components.Authorization nos componentes:

@using Microsoft.AspNetCore.Components.Authorization;

Confirme ou altere o componente de exibição de rota para um AuthorizeRouteView na definição do componente Router. A localização do componente Router difere dependendo do tipo de aplicativo. Use a pesquisa para localizar o componente se você não souber a localização dele no projeto.

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

Observação

Quando você cria um aplicativo do Blazor de um dos modelos de projeto do Blazor com a autenticação habilitada, o aplicativo inclui o componente AuthorizeRouteView. Para mais informações, consulte Autenticação e autorização do ASP.NET Core Blazor com informações adicionais apresentadas na seção Personalizar conteúdo não autorizado com o componente Router.

Onde o componente Router está localizado:

A localização do componente Router difere dependendo do tipo de aplicativo. Use a pesquisa para localizar o componente se você não souber a localização dele no projeto.

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

Observação

Quando você cria um aplicativo do Blazor de um dos modelos de projeto do Blazor com a autenticação habilitada, o aplicativo inclui os componentes AuthorizeRouteView e CascadingAuthenticationState. Para mais informações, consulte Autenticação e autorização do ASP.NET Core Blazor com informações adicionais apresentadas na seção Personalizar conteúdo não autorizado com o componente Router.

O componente de exemplo AuthorizeView a seguir demonstra o nome do usuário autenticado:

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

Para obter diretrizes sobre o uso do AuthorizeView, consulte Autenticação e autorização Blazor do ASP.NET Core.

Notificações de alteração de estado de autenticação

Um AuthenticationStateProvider personalizado pode invocar NotifyAuthenticationStateChanged na classe base AuthenticationStateProvider para notificar os consumidores sobre a alteração de estado de autenticação a ser gerada novamente.

O exemplo a seguir baseia-se na implementação de um AuthenticationStateProvider personalizado seguindo as diretrizes na seção Implementar um AuthenticationStateProvider personalizado deste artigo. Se você já seguiu as diretrizes dessa seção, o seguinte CustomAuthStateProvider substitui o mostrado na seção.

A implementação CustomAuthStateProvider a seguir expõe um método personalizado, AuthenticateUser, para conectar um usuário e notificar os consumidores sobre a alteração do estado de autenticação.

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)));
    }
}

Observação

O código anterior que cria um novo ClaimsIdentity usa a inicialização de coleção simplificada introduzida com o C# 12 (.NET 8). Para mais informações, consulte Expressões de coleção – Referência da linguagem C#.

Em um 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);
    }
}

A abordagem anterior pode ser aprimorada para disparar notificações de alterações de estado de autenticação por meio de um serviço personalizado. A classe CustomAuthenticationService a seguir mantém a entidade de segurança de declarações do usuário atual em um campo de suporte (currentUser) com um evento (UserChanged) que o provedor de estado de autenticação pode assinar, em que o evento invoca NotifyAuthenticationStateChanged. Com a configuração adicional mais adiante nesta seção, CustomAuthenticationService pode ser injetado em um componente com lógica que define o CurrentUser para disparar o 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);
            }
        }
    }
}

No arquivo Program, registre o CustomAuthenticationService no contêiner de injeção de dependência:

builder.Services.AddScoped<CustomAuthenticationService>();

No Startup.ConfigureServices de Startup.cs, registre o CustomAuthenticationService no contêiner de injeção de dependência:

services.AddScoped<CustomAuthenticationService>();

No arquivo Program, registre o CustomAuthenticationService no contêiner de injeção de dependência:

builder.Services.AddSingleton<CustomAuthenticationService>();

O CustomAuthStateProvider a seguir assina o evento CustomAuthenticationService.UserChanged. O método GetAuthenticationStateAsync retorna o estado de autenticação do usuário. Inicialmente, o estado de autenticação é baseado no valor de CustomAuthenticationService.CurrentUser. Quando o usuário muda, um novo estado de autenticação é criado para o novo usuário (new AuthenticationState(newUser)) para chamadas para 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);
}

O método SignIn do componente a seguir cria uma entidade de segurança de declarações para que o identificador do usuário seja definido em 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;
    }
}

Observação

O código anterior que cria um novo ClaimsIdentity usa a inicialização de coleção simplificada introduzida com o C# 12 (.NET 8). Para mais informações, consulte Expressões de coleção – Referência da linguagem C#.

Recursos adicionais