ASP .NET Core Blazor - Gerenciando Usuários e Perfis - I

 Neste artigo veremos como gerenciar users e roles em uma aplicação ASP .NET Core Blazor usando o .NET Core 3.0.

Podemos criar uma página de administração simples para permitir gerenciar usuários realizando tarefas como criação, atualização e exclusão de usuários em uma aplicação Blazor do lado do servidor.

Isso pode ser feito usando apenas único componente Blazor em nosso projeto, e também podemos atualizar as senhas dos usuários.

Para implementar isso vamos criar via código uma função de Administrador no membership Microsoft ASP.NET Core Identity e fornecer via código acesso de administrador a um usuário designado (colocando-o na função Administradores).

Vejamos então como implementar estas funcionalidades.

Recursos usados:

Criando o projeto Blazor (Server side) no VS Community 2019

Abra o VS 2019 Community (versão mínima 16.3) e selecione a opção Create a New Project;

A seguir selecione a opção Blazor app e clique em next;

Informe o nome do projeto :  BlazorAutenticacao, a localização e clique em Create;

A seguir teremos uma janela com duas opções :

  1. Blazor Server App
  2. Blazor WebAssembly App

Selecione a primeira opção - Blazor Server App - e clique em Change para alterar a autenticação:

A seguir selecione a opção - Individual User Accounts - e escolha : Store user accounts in app, e clique em OK;

A seguir clique no botão Create para criar o projeto.

Incluindo o suporte a Roles

Com o projeto criado vamos abrir o arquivo Startup.cs e para poder dar suporte a Roles vamos alterar seguinte linha de código no método ConfigureServices:

  services.AddDefaultIdentity<IdentityUser>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

Para:

    public void ConfigureServices(IServiceCollection services)
     {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity<IdentityUser>()
               .AddRoles<IdentityRole>()
               .AddEntityFrameworkStores<ApplicationDbContext>();
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddScoped<AuthenticationStateProvider, 
                        RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
            services.AddSingleton<WeatherForecastService>();
   }

Criando o componente Administrador.razor

Vamos incluir um componente Administrador.razor na pasta Pages do projeto com o código abaixo:

@page "/administrador"
@using Microsoft.AspNetCore.Authorization;
@using Microsoft.AspNetCore.Identity;
@inject UserManager<IdentityUser> _UserManager
@inject RoleManager<IdentityRole> _RoleManager
@inject AuthenticationStateProvider AuthenticationStateProvider
<h3>Administração</h3>
<AuthorizeView>
    <Authorized>
        @if (@context.User.IsInRole(ADMINISTRATION_ROLE))
        {
            <p>Você esta com perfil : @ADMINISTRATION_ROLE </p>
        }
        else
        {
            <p>Você não esta logado como um perfil de : @ADMINISTRATION_ROLE.</p>
        }
    </Authorized>
    <NotAuthorized>
        <p>Você não esta logado.</p>
    </NotAuthorized>
</AuthorizeView>
@code {
    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    string ADMINISTRATION_ROLE = "Administrators";

    System.Security.Claims.ClaimsPrincipal UsuarioAtual;

    protected override async Task OnInitializedAsync()
    {
        // Verifica se existe um ADMINISTRATION_ROLE
        var RoleResult = await _RoleManager.FindByNameAsync(ADMINISTRATION_ROLE);
        if (RoleResult == null)
        {
            // Cria o perfil ADMINISTRATION_ROLE
            await _RoleManager.CreateAsync(new IdentityRole(ADMINISTRATION_ROLE));
        }
        // Verifica que o usuário chamado Admin@BlazorHelp.com é um Administrador
        var user = await _UserManager.FindByNameAsync("Admin@BlazorHelp.com");
        if (user != null)
        {
            // O usuário Admin@BlazorHelp.com esta no perfil de administrador?
            var UserResult = await _UserManager.IsInRoleAsync(user, ADMINISTRATION_ROLE);
            if (!UserResult)
            {
                // Põe o admin no perfil Administrator
                await _UserManager.AddToRoleAsync(user, ADMINISTRATION_ROLE);
            }
        }
        // Obtem o usuário logado atual
        UsuarioAtual = (await authenticationStateTask).User;
    }
}

Este código vai incluir o usuário Admin@BlazorHelp.com na Role Administrators, e, vai verificar se os usuários estão logados ou não, e, se estiverem vai informar se eles estão incluídos no perfil Administrators.

A seguir vamos incluir um item no menu lateral incluindo o código abaixo no arquivo NavMenu.razor na pasta Shared:

          <li class="nav-item px-3">
            <NavLink class="nav-link" href="administrador">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Administração
            </NavLink>
        </li>

Agora podemos executar o projeto pressionando F5.

Com isso iremos obter o seguinte resultado:

Vamos clicar no link Register e registrar um novo usuário chamado : Admin@BlazorHelp.com

Informando o email e uma senha forte, ao clicar no botão Register iremos obter o seguinte página do Migrations do EF Core:

Para continuar basta clicar no botão - Apply Migrations e a seguir atualizar a página. Com isso iremos visualizar a página abaixo:

Com isso vemos que nosso usuário - Admin@BlazorHelp.com foi registrado e estamos logados.

Clicando no link - Administração - iremos obter a seguinte mensagem :

Esta mensagem esta informando que você não está na função Administradores (mesmo que o código tenha sido executado, porque você navegou para essa página, para adicionar sua conta a esse Perfil).

Clique em Log out, e a seguir refaça o Login usando o usuário Admin@BlazorHelp.com, e, a seguir clique novamente no link Administração.

Agora você irá obter:

Agora sim o usuário esta sendo reconhecido como fazendo parte do perfil Adminstrators.

Teremos somente esse usuário com perfil de administrador, e, não importa quantos usuários você tente registrar todos eles não farão parte do perfil Administrators.

Vamos agora implementar as funcionalidades para gerenciar os usuários.

Gerenciando usuários :  Criando uma lista de usuários

Vamos iniciar o gerenciamento de usuários começando a listar os usuários atuais existentes e registrados na aplicação.

Primeiro, vamos adicionar alguns campos e variáveis à seção @code ao componente Administrador.razor que precisaremos agora e para dar suporte ao código que adicionaremos mais adiante no artigo.

..
@code {
    // Propriedade usada para adicionar ou editar o usuário atual
    IdentityUser objUser = new IdentityUser();
    // Obtem a role selecionada para o usuário atual
    string CurrentUserRole { get; set; } = "Users";
    // Coleção para exibir os usuários existentes
    List<IdentityUser> ColUsers = new List<IdentityUser>();
    // Opções para exibir as roles na lista suspensa quando editar um usuário
    List<string> Options = new List<string>() { "Users", "Administrators" };
    // Trata erros
    string strError = "";
    // Habilita a exibição do Popup
    bool MostraPopup = false;

..
 

Agora vamos definir os métodos vazios (stubs) que iremos usar para implementar cada funcionalidade que vai gerenciar os usuários em nossa aplicação.

Vamos adicionar esses métodos agora porque a marcação que adicionaremos em breve se referirá a esses métodos, e o código não será compilado se os métodos não existirem (mesmo que, nesse momento, os métodos não executem nenhuma funcionalidade ).

Ainda no arquivo Adminstrador.razor, na seção @code inclua:

    ...  
    void AdicionaNovoUser()
    { }
    async Task SalvaUser()
    {}
    async Task EditaUser(IdentityUser _IdentityUser)
    {}
    async Task DeletaUser()
    {}
    void FechaPopup()
    {
        // Fecha o Popup
        MostraPopup = false;
    }

    public void GetUsers()
    {}
  ...

Como vamos começar listando os usuários vamos implementar o código abaixo no método GetUsers():

    public void GetUsers()
    {
        // limpa mensasgens de erro
        strError = "";
        // define a coleção para tratar os usuários
        ColUsers = new List<IdentityUser>();
        // Obtem os usuários a partir de _UserManager
        var user = _UserManager.Users.Select(x => new IdentityUser
        {
            Id = x.Id,
            UserName = x.UserName,
            Email = x.Email,
            PasswordHash = "*****"
        });
        foreach (var item in user)
        {
            ColUsers.Add(item);
        }
    }

Agora, adicionar o código a seguir no final do método protected override async Task OnInitializedAsync() no arquivo Administardor.razor, para que o método GetUsers() seja chamado quando o usuário navegar para a página.

Para concluir essa implementação vamos incluir o código abaixo no início do arquivo Administrador.razor que vai exibir os usuários:

...

<table class="table">
    <thead>
        <tr>
            <th>Id</th>
            <th>Nome</th>
            <th>Email</th>
        </tr>

    </thead>
    <tbody>
        @foreach (var user in ColUsers)
        {
            <tr>
                <td>@user.Id.Substring(0, 5) ...</td>
                <td>@user.UserName</td>
                <td>@user.Email</td>

                <td>
                    <button class="btn btn-primary"
                           @onclick="(() => EditUser(user))">
                        Editar
                    </button>

                </td>
            </tr>
        }
    </tbody>
</table>
...

Agora podemos testar executando o projeto e fazendo o login usando um usuário já registrado e a seguir acionando a opção Administração, o que nos dará o seguinte resultado:

Aqui eu fiz o login com o usuário : Macoratti@yahoo.com.

O botão Editar que aparece na página ainda não tem funcionalidade.

Na próxima parte do artigo vamos continuar implementando as demais funcionalidades do gerenciamento dos usuários no Blazor.

"E tu, ó menino, serás chamado profeta do Altíssimo, Porque hás de ir ante a face do Senhor, a preparar os seus caminhos;
Para dar ao seu povo conhecimento da salvação, Na remissão dos seus pecados;
Pelas entranhas da misericórdia do nosso Deus, Com que o oriente do alto nos visitou;"
Lucas 1:76-78
 

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?


Referências:


José Carlos Macoratti