Como instalar e configurar a ASP.NET Core Identity - I


 Hoje vamos apresentar os procedimentos básicos de como instalar e configurar o Identity usando a ASP .NET Core.

A ASP.NET Core Identity é um kit de ferramentas e uma API com a qual você pode criar recursos de autorização e autenticação em seu aplicativo.

Os usuários podem criar uma conta e fazer login com um nome de usuário e senha, e existe também o recurso de Roles ou Perfis e gerenciamento Perfis.

A forma padrão usada pela ASP.NET Core Identity para persistir as informações do usuário como nome, senhas, perfis, etc. é usar um banco de dados SQL Server, mas podemos usar outro banco de dados relacionais.

Neste artigo vamos usar o SQL Server e o Visual Studio 2019 com o .NET 5.0.

Criando o projeto no VS 2019

Vamos criar um projeto no VS 2019 usando o template ASP.NET Core Empty chamado DemoIdentity usando a opção do .NET 5.0 (Current) ou .NET 6.0 se preferir:

Com isso teremos um projeto com dependências mínimos e com a seguinte estrutura:

Vamos iniciar a configuração do Identity instalando os seguintes pacotes no projeto:

Podemos fazer isso usando a janela do Package Manager Console e digitando o comando: 

 install-package <nome_pacote>

Ao final teremos os pacotes instalados no projeto conforme mostrado abaixo:

Configurando o projeto

Vamos iniciar a configuração do projeto abrindo o arquivo Startup e incluindo o código em destaque mostrado a seguir:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace DemoIdentity
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });

        }
    }
}

Vamos agora instalar o Bootstrap para estilizar as views que iremos usar. (Vou instalar a versão 4.5.0)

Portanto, primeiro crie uma nova pasta chamada wwwroot na raiz do projeto e, a seguir, clique com o botão direito nela e selecione Add -> Client-Side Library.

Teremos uma nova janela chamada Add Client-Side Library, aqui pesquise twitter-bootstrap na caixa de texto da biblioteca e clique no botão Instalar.

A seguir vamos criar as seguintes pastas no projeto:

Dentro da pasta Shared vamos criar o arquivo _Layout.cshtml :

Neste arquivo vamos incluir o código abaixo:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="~/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
</head>
<body class="m-1 p-1">
    @RenderBody()
</body>
</html>

A seguir clique com o botão direito na pasta Views e selecione Add ->New Item.

Na lista de itens, selecione Razor View Imports e clique no botão Add.

Isso adicionará o arquivo _ViewImports.cshtml:

Inclua neste arquivo o código abaixo:

@using DemoIdentity.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers    

Aqui importamos as tag helpers e o namespace DemoIdentity.Models.

Repita o procedimento e clique com o botão direito na pasta Views e selecione Add -> New Item.

Na lista de itens, selecione Razor View Start e clique no botão Add.

Isso irá incluir o arquivo _ViewStart.cshtml no projeto.

Inclua agora o código abaixo neste arquivo:

@{
     Layout = "_Layout";      
}   

Este arquivo informa para todas as views usar o leiaute definido no arquivo _Layout.cshtml na pasta Shared.

Configurando a ASP .NET Core Identity

O processo de configuração do Identity envolve a criação de novas classes de modelo, alterações de configuração, controladores e ações para oferecer suporte a operações de autenticação e autorização.

Vamos iniciar criando a classe AppUser na pasta Models que vai definir os usuários da aplicação. Esses usuários são armazenados no banco de dados SQL Server.

A classe User deve ser derivada da classe IdentityUser do namespace Microsoft.AspNetCore.Identity.

using Microsoft.AspNetCore.Identity;

namespace DemoIdentity.Models
{
    public class AppUser : IdentityUser       
    {
    }
}

Observe que a classe AppUser não contém nenhuma propriedade ou método. Isso ocorre porque a classe IdentityUser fornece a ele algumas das propriedades, como nome de usuário, e-mail, número de telefone, hash de senha, roles e etc.

Se você quiser mais propriedades que não estão definidas na classe IdentityUser, certamente poderá adicioná-las à sua classe de usuário. Veremos isso em outro artigo.

As propriedades da classe IdentityUser são definidas a seguir:

Nome Descrição
Id Contém o Id único do usuário
UserName Contém o nome do usuário
Claims Retorna todas as claims para o usuário
Email Contém o email do usuário
PasswordHash Contém o hash da senha do usuário
Roles Retorna todas as roles do usuário
PhoneNumber   Retorna o telefone do usuário
SecurityStamp  Contém o valor que é alterado sempre que usuário for alterado

Precisamos agora criar a classe de contexto que vai usar o EF Core para realizar o mapeamento ORM.

Definindo o contexto, a string de conexão e o serviço

Vamos criar uma pasta Context no projeto e nesta pasta criar a classe AppIdentityContext que vai herdar de IdentityDbContext<AppUser> onde AppUser é a classe que representa o usuário e que criamos na pasta Models.

using DemoIdentity.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace DemoIdentity.Context
{
    public class AppIdentityContext : IdentityDbContext<AppUser>
    {
        public AppIdentityContext(DbContextOptions<AppIdentityContext> options) : base(options) { }
    }
}

Note que não criamos nenhuma propriedade ou método nesta classe pois ela herda da classe IdentityDbContext e esta herdando todas as suas propriedades e métodos.

Vamos definir no arquivo appsettings.json a string de conexão que iremos usar para acessar o banco de dados SQL Server:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.\\sqlexpress;Database= IdentityDemoDB;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

A string de conexão do banco de dados, que contém o nome do banco de dados, o nome de usuário e a senha para se conectar ao banco de dados, é principalmente armazenada no arquivo appsettings.json. Este arquivo deve ser criado na pasta raiz do projeto se não existir.

Vejamos a estrutura da string de conexão:

Agora, preciso atualizar o arquivo Startup.cs para que o aplicativo possa ler a string de conexão do arquivo appsettings.json.

Abra o arquivo Startup e inclua o código em destaque mostrado a seguir:

using DemoIdentity.Context;
using DemoIdentity.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace DemoIdentity
{
    public class Startup
    {
        public Startup(IConfiguration configuration) => Configuration = configuration;
        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<AppIdentityContext>(options => 
              options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
            services.AddIdentity<AppUser, IdentityRole>()
                .AddEntityFrameworkStores<AppIdentityContext>().AddDefaultTokenProviders();
            services.AddControllersWithViews();
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Vamos entender o que foi configurado com a inclusão deste código:

- Primeiro incluímos um construtor para receber um objeto do tipo IConfiguration. Ele será fornecido pelo recurso Dependency Injection do ASP.NET Core.

        public Startup(IConfiguration configuration) => Configuration = configuration;
        public IConfiguration Configuration { get; }


A seguir, dentro do método ConfigureServices() usamos o método AddDbContext() para aplicar a classe de contexto do banco de dados e definimos que ele usará o banco de dados SQL Server cuja string de conexão é obtida do arquivo de configuração do aplicativo, que no artigo é o arquivo appsettings.json.

       services.AddDbContext<AppIdentityContext>(options =>
              options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));


A seguir definimos a configuração do Identity da ASP .NET Core :

  services.AddIdentity<AppUser, IdentityRole>()
                .AddEntityFrameworkStores<AppIdentityContext>().AddDefaultTokenProviders();


Este código especifica que:

Para concluir incluímos o middleware de autenticação no método Configure() incluindo o código:  app.UseAuthentication().

Isso significa que em cada solicitação HTTP, as credenciais do usuário serão adicionadas a um cookie ou URL. Isso associará um determinado usuário à solicitação HTTP feita para a aplicação.

Criando o banco de dados no SQL Server

Com isso temos tudo pronto e já podemos criar o banco de dados no SQL Server usando o EF Core Migrations

Para executar os comandos de migração, vamos usar a janela do console do gerenciador de pacotes. (Package Manager Console)

Você também precisará instalar a ferramenta dotnet ef para executar e gerenciar as migrações.

Instale o dotnet ef executando o seguinte comando na janela do console do gerenciador de pacotes:

dotnet tool install --global dotnet-ef

Após fazer a instalação verifique digitando o comando : dotnet ef

Você deverá obter o seguinte resultado:

Em seguida, você precisa ir para o diretório do arquivo Startup.cs do projeto. Para isso, execute o comando dir na janela do console do gerenciador de pacotes. O comando dir dirá a localização do diretório atual.

Posicione-se no pasta do projeto digitando:  cd ./DemoIdentity e a seguir emita o comando dir. Você deverá ver o arquivo Startup.cs :



A seguir execute o comando para criar o script de migração:

dotnet ef migrations add MigrationInicial

Este comando vai criar o arquivo com os comandos SQL para criar o banco de dados e as tabelas e vai criar no projeto a pasta Migrations com os arquivos para gerenciar as migrações.

Para aplicar a migração e executar os comandos SQL execute o comando: dotnet ef database update

Abrindo o SQL Server Management Studio podemos confirmar a criação do banco de dados IdentityDemoDb e das tabelas do Identity:

Podemos visualizar o relacionamento entre as tabelas do Identity gerando um diagrama abaixo:

Isso conclui o procedimento de configuração de identidade em nosso aplicativo. Agora podemos adicionar usuários, gerenciar usuários, adicionar funções, adicionar usuários a funções, fazer autenticação de usuário e muitas outras coisas com o Identity.

Para aprender como gerenciar os usuários, Roles, Claims e outros recursos do Identity acompanhe a série de artigos iniciada com o artigo : ASP .NET Core - Usando o Identity de cabo a rabo - I

"(Disse Jesus) Eu sou a videira verdadeira, e meu Pai é o agricultor.
Todo ramo que, estando em mim, não der fruto, ele o corta; e todo o que dá fruto limpa, para que produza mais fruto ainda."

João 15:1,2

Referências:


José Carlos Macoratti