Introdução ao Identity no ASP.NET Core

ASP.NET Core Identity:

  • É uma API que suporta a funcionalidade de login da interface do usuário (UI).
  • Gerencia usuários, senhas, dados de perfil, funções, declarações, tokens, confirmação de e-mail e muito mais.

Os utilizadores podem criar uma conta com as informações de login armazenadas em Identity ou podem usar um provedor de login externo. Os fornecedores de início de sessão externos suportados incluem o Facebook, o Google, a Conta Microsoft e o Twitter.

Para informações sobre como exigir autenticação para todos os utilizadores da aplicação, consulte Crie uma aplicação ASP.NET Core com dados de utilizador protegidos por autorização.

O código-fonte Identity está disponível em GitHub. Andaime Identity e exiba os arquivos gerados para revisar a interação do modelo com Identityo .

O Identity é normalmente configurado usando uma base de dados SQL Server para armazenar nomes de utilizador, palavras-passe e dados de perfil. Em alternativa, pode ser usado outro armazenamento persistente, por exemplo, o Armazenamento de Tabelas do Azure.

Neste tópico, você aprenderá a usar Identity para registrar, fazer login e logout de um usuário. Nota: os modelos tratam o nome de utilizador e o e-mail como o mesmo para os utilizadores. Para obter instruções mais detalhadas sobre como criar aplicações que usam Identity, consulte Próximas etapas.

Para mais informações sobre Identity nas aplicações Blazor, consulte ASP.NET Core Blazor autenticação e autorização e os artigos que se seguem na documentação Blazor.

ASP.NET Core Identity não está relacionado com a plataforma de identidades da Microsoft. A plataforma de identidade da Microsoft é:

  • Uma evolução da plataforma de programadores Azure Active Directory (Azure AD).
  • Uma solução alternativa de identidade para autenticação e autorização em aplicações ASP.NET Core.

ASP.NET Core Identity adiciona funcionalidade de login à interface de utilizador (UI) das aplicações web ASP.NET Core. Para proteger APIs da Web e SPAs, use uma das seguintes opções:

Duende Identity Server é um framework OpenID Connect e OAuth 2.0 para ASP.NET Core. O Duende Server habilita os seguintes recursos de Identity segurança:

  • Autenticação como serviço (AaaS)
  • Logon único/desligamento (SSO) em vários tipos de aplicativos
  • controlo de acesso a APIs
  • Gateway de Federação

Important

A Duende Software pode exigir que você pague uma taxa de licença pelo uso de produção do Duende Identity Server. Para mais informações, veja Migrar de ASP.NET Core em .NET 5 para .NET 6.

Para obter mais informações, consulte a documentação do Duende Identity Server (site da Duende Software).

Ver ou descarregar o código de exemplo (como descarregar).

Crie um Blazor Web App com autenticação

Crie um ASP.NET Core Blazor Web App project com Contas Individuais.

Note

Para obter uma Razor experiência do Pages, consulte a seção Criar um Razor aplicativo Pages com autenticação .

Para obter uma experiência MVC, consulte a seção Criar um aplicativo MVC com autenticação .

  • Selecione o Blazor Web App modelo. Selecione Avançar.
  • Faça as seguintes seleções:
    • Tipo de autenticação: Contas individuais
    • Modo de renderização interativo: Server
    • Localização da Interatividade: Global
  • Selecione Criar.

O projeto gerado inclui os componentes IdentityRazor. Os componentes encontram-se na pasta Components/Account do projeto do servidor. Por exemplo:

  • Components/Account/Pages/Register.razor
  • Components/Account/Pages/Login.razor
  • Components/Account/Pages/Manage/ChangePassword.razor

Identity Razor Os componentes são descritos individualmente na documentação para casos de uso específicos e estão sujeitos a alterações a cada versão. Quando geras um Blazor Web App com Contas Individuais, os componentes IdentityRazor são incluídos no projeto gerado. Os componentes IdentityRazor também podem ser inspecionados na pasta Components/Account do projeto do servidor no modelo de projeto Blazor Web App (dotnet/aspnetcore repositório GitHub).

Note

Os links de documentação para a fonte de referência .NET normalmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para mais informações, consulte Como selecionar uma etiqueta de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Para mais informações, consulte ASP.NET Core Blazor autenticação e autorização e os artigos que se seguem na documentação Blazor. A maioria dos artigos na área Security e Identity do conjunto principal de documentação ASP.NET Core aplica-se a aplicações Blazor. No entanto, o Blazor conjunto de documentação contém artigos e orientações que substituem ou adicionam informações. Recomendamos estudar primeiro o conjunto geral de documentação ASP.NET Core, seguido do acesso aos artigos na documentação BlazorSecurity e Identity.

Criar uma Razor aplicação Páginas com autenticação

Crie uma Aplicação Web do ASP.NET Core com Páginas (Razor) e Contas Individuais.

  • Selecione o modelo da Aplicação Web ASP.NET Core (Razor Páginas). Selecione Avançar.
  • Em Tipo de autenticação, selecione Contas individuais.
  • Selecione Criar.

O projeto gerado fornece ASP.NET Core Identity como uma biblioteca de classes Razor (RCL). A biblioteca de classes IdentityRazor expõe endpoints com a área Identity. Por exemplo:

  • Areas/Identity/Pages/Account/Register
  • Areas/Identity/Pages/Account/Login
  • Areas/Identity/Pages/Account/Manage/ChangePassword

As páginas são descritas individualmente na documentação para casos de uso específicos e estão sujeitas a alterações a cada versão. Para visualizar todas as páginas no RCL, consulte a referência de origem ASP.NET Core (repositório GitHub, ). Você pode estruturar páginas individuais ou todas as páginas no app. Para mais informações, consulte Scaffold Identity em projetos ASP.NET Core.

Criar um aplicativo MVC com autenticação

Crie um project MVC ASP.NET Core com Contas Individuais.

  • Selecione o modelo ASP.NET Core (Modelo-Visualização-Controlador) da Aplicação Web. Selecione Avançar.
  • Em Tipo de autenticação, selecione Contas individuais.
  • Selecione Criar.

O projeto gerado fornece ASP.NET Core Identity como uma biblioteca de classes Razor (RCL). A IdentityRazor biblioteca de classes é baseada em Razor Pages e expõe endpoints com a Identity área. Por exemplo:

  • Areas/Identity/Pages/Account/Register
  • Areas/Identity/Pages/Account/Login
  • Areas/Identity/Pages/Account/Manage/ChangePassword

As páginas são descritas individualmente na documentação para casos de uso específicos e estão sujeitas a alterações a cada versão. Para visualizar todas as páginas no RCL, consulte a referência de origem ASP.NET Core (repositório GitHub, ). Você pode estruturar páginas individuais ou todas as páginas no app. Para mais informações, consulte Scaffold Identity em projetos ASP.NET Core.

Aplicar migrações

Aplique as migrações para inicializar o banco de dados.

Execute o seguinte comando na Gestor de Pacotes Console (PMC):

Update-Database

Registo de Teste e Início de Sessão

Execute o aplicativo e registre um usuário. Dependendo do tamanho do ecrã, poderá ter de selecionar o botão de alternância de navegação para ver as ligações Registar e Iniciar sessão .

Ver a Identity base de dados

  • No menu View, selecione SQL Server Object Explorer (SSOX).
  • Navegue até (localdb)MSSQLLocalDB(SQL Server 13). Clique com o botão direito do rato em dbo.AspNetUsers>Ver Dados

Menu contextual na tabela AspNetUsers em SQL Server Object Explorer

Configurar Identity serviços

Os serviços são adicionados em Program.cs. O padrão típico é chamar métodos na seguinte ordem:

  1. Add{Service}
  2. builder.Services.Configure{Service}
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();

builder.Services.Configure<IdentityOptions>(options =>
{
    // Password settings.
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 1;

    // Lockout settings.
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;

    // User settings.
    options.User.AllowedUserNameCharacters =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
    options.User.RequireUniqueEmail = false;
});

builder.Services.ConfigureApplicationCookie(options =>
{
    // Cookie settings
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

    options.LoginPath = "/Identity/Account/Login";
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.SlidingExpiration = true;
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

O código precedente configura Identity com valores padrão de opção. Os serviços são disponibilizados para o aplicativo por meio de injeção de dependência.

Identity é ativado chamando UseAuthentication. UseAuthentication Adiciona middleware de autenticação ao pipeline de solicitação.

O aplicativo gerado por modelo não usa autorização. app.UseAuthorization está incluído para garantir que é adicionado na ordem correta caso o aplicativo adicione autorização. UseRouting, UseAuthenticatione UseAuthorization deve ser chamado na ordem indicada no código anterior.

Para obter mais informações sobre o IdentityOptions, consulte IdentityOptions e Arranque da Aplicação.

Métricas ASP.NET Core Identity

As métricas ASP.NET Core Identity fornecem capacidades de monitorização para processos de gestão e autenticação de utilizadores. Essas métricas ajudam a detetar padrões de entrada incomuns que podem indicar ameaças à segurança, acompanhar o desempenho das operações de identidade e entender como os usuários interagem com recursos de autenticação, como a autenticação de dois fatores. Essa observabilidade é particularmente valiosa para aplicativos com requisitos de segurança rigorosos ou aqueles com alto tráfego de autenticação.

Para detalhes completos sobre métricas disponíveis e como as utilizar, consulte ASP.NET Core métricas.

Modelar Registo, Iniciar Sessão, Terminar Sessão e Confirmação de Registo

Adicione os Registerficheiros , Login, LogOut, e RegisterConfirmation . Siga as instruções de Scaffold Identity em um projeto Razor com autorização para gerar o código mostrado nesta secção.

Examinar Registo

Quando um usuário clica no botão Registrar na Register página, a RegisterModel.OnPostAsync ação é invocada. O usuário é criado por CreateAsync(TUser) no _userManager objeto:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Desativar a verificação de conta padrão

Com os modelos padrão, o usuário é redirecionado para o Account.RegisterConfirmation local onde pode selecionar um link para ter a conta confirmada. O padrão Account.RegisterConfirmation é usado apenas para testes, a verificação automática de conta deve ser desabilitada em um aplicativo de produção.

Para exigir uma conta confirmada e impedir o login imediato no registro, defina DisplayConfirmAccountLink = false em /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs:

[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IEmailSender _sender;

    public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
    {
        _userManager = userManager;
        _sender = sender;
    }

    public string Email { get; set; }

    public bool DisplayConfirmAccountLink { get; set; }

    public string EmailConfirmationUrl { get; set; }

    public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
    {
        if (email == null)
        {
            return RedirectToPage("/Index");
        }

        var user = await _userManager.FindByEmailAsync(email);
        if (user == null)
        {
            return NotFound($"Unable to load user with email '{email}'.");
        }

        Email = email;
        // Once you add a real email sender, you should remove this code that lets you confirm the account
        DisplayConfirmAccountLink = false;
        if (DisplayConfirmAccountLink)
        {
            var userId = await _userManager.GetUserIdAsync(user);
            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            EmailConfirmationUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
                protocol: Request.Scheme);
        }

        return Page();
    }
}

Iniciar sessão

O formulário de login é exibido quando:

  • O link Entrar está selecionado.
  • Um utilizador tenta aceder a uma página restrita a que não está autorizado a aceder ou quando não está autenticado pelo sistema.

Quando o formulário na página de Login é enviado, a ação OnPostAsync é chamada. PasswordSignInAsync é chamado no objeto _signInManager.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Para informações sobre como tomar decisões de autorização, consulte Introdução à autorização em ASP.NET Core.

Terminar sessão

O link Sair invoca a LogoutModel.OnPost ação.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

No código anterior, o código return RedirectToPage(); precisa ser um redirecionamento para que o navegador execute uma nova solicitação e a identidade do usuário seja atualizada.

SignOutAsync Limpa as reivindicações do utilizador armazenadas num cookie.

O posto é especificado em Pages/Shared/_LoginPartial.cshtml:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Teste Identity

Os modelos padrão de project web permitem acesso anónimo às páginas iniciais. Para testar Identity, adicione [Authorize]:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Se tiver sessão iniciada, termine-a. Execute a aplicação e selecione a Privacy hiperligação. Você será redirecionado para a página de login.

Explorar Identity

Para explorar Identity mais detalhadamente:

Componentes do Identity

Todos os pacotes NuGet dependentes de Identity estão incluídos no framework partilhado ASP.NET Core.

O pacote principal para Identity é Microsoft.AspNetCore.Identity. Este pacote contém o conjunto central de interfaces para ASP.NET Core Identity, e está incluído por Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Migração para ASP.NET Core Identity

Para obter mais informações e orientações sobre como migrar o seu armazenamento existente Identity, consulte Migrar autenticação e Identity.

Definindo a força da senha

Consulte Configuração para obter um exemplo que define os requisitos mínimos de senha.

AddDefaultIdentity e AddIdentity

AddDefaultIdentity foi introduzido em ASP.NET Core 2.1. Chamar AddDefaultIdentity é semelhante a chamar o seguinte:

Consulte AddDefaultIdentity source para obter mais informações.

Impedir a publicação de ativos estáticos Identity

Para evitar publicar ativos estáticos Identity (folhas de estilo e ficheiros JavaScript para Identity UI) na raiz web, adicione a seguinte propriedade ResolveStaticWebAssetsInputsDependsOn e o alvo RemoveIdentityAssets ao ficheiro de projeto da aplicação.

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

Próximas Etapas

Por Rick Anderson

ASP.NET Core Identity:

  • É uma API que suporta a funcionalidade de login da interface do usuário (UI).
  • Gerencia usuários, senhas, dados de perfil, funções, declarações, tokens, confirmação de e-mail e muito mais.

Os utilizadores podem criar uma conta com as informações de login armazenadas em Identity ou podem usar um provedor de login externo. Os fornecedores de início de sessão externos suportados incluem o Facebook, o Google, a Conta Microsoft e o Twitter.

Para informações sobre como exigir autenticação para todos os utilizadores da aplicação, consulte Crie uma aplicação ASP.NET Core com dados de utilizador protegidos por autorização.

O código-fonte Identity está disponível em GitHub. Andaime Identity e exiba os arquivos gerados para revisar a interação do modelo com Identityo .

O Identity é normalmente configurado usando uma base de dados SQL Server para armazenar nomes de utilizador, palavras-passe e dados de perfil. Em alternativa, pode ser usado outro armazenamento persistente, por exemplo, o Armazenamento de Tabelas do Azure.

Neste tópico, você aprenderá a usar Identity para registrar, fazer login e logout de um usuário. Nota: os modelos tratam o nome de utilizador e o e-mail como o mesmo para os utilizadores. Para obter instruções mais detalhadas sobre como criar aplicações que usam Identity, consulte Próximas etapas.

ASP.NET Core Identity não está relacionado com a plataforma de identidades da Microsoft. A plataforma de identidade da Microsoft é:

  • Uma evolução da plataforma de programadores Azure Active Directory (Azure AD).
  • Uma solução alternativa de identidade para autenticação e autorização em aplicações ASP.NET Core.

ASP.NET Core Identity adiciona funcionalidade de login à interface de utilizador (UI) das aplicações web ASP.NET Core. Para proteger APIs da Web e SPAs, use uma das seguintes opções:

Duende Identity Server é um framework OpenID Connect e OAuth 2.0 para ASP.NET Core. O Duende Server habilita os seguintes recursos de Identity segurança:

  • Autenticação como serviço (AaaS)
  • Logon único/desligamento (SSO) em vários tipos de aplicativos
  • controlo de acesso a APIs
  • Gateway de Federação

Important

A Duende Software pode exigir que você pague uma taxa de licença pelo uso de produção do Duende Identity Server. Para mais informações, veja Migrar de ASP.NET Core em .NET 5 para .NET 6.

Para obter mais informações, consulte a documentação do Duende Identity Server (site da Duende Software).

Ver ou descarregar o código de exemplo (como descarregar).

Criar um aplicativo Web com autenticação

Crie um projeto de Aplicação Web ASP.NET Core com Contas de Utilizador Individuais.

  • Selecione o modelo ASP.NET Core Web App. Nomeie o projeto WebApp1 para que tenha o mesmo espaço de nomes do projeto de download. Clique em OK.
  • Na entrada Tipo de autenticação , selecione Contas de usuário individuais.

O projeto gerado fornece ASP.NET Core Identity como uma Razorbiblioteca de classes. A biblioteca de classes IdentityRazor expõe endpoints com a área Identity. Por exemplo:

  • /Identity/Conta/Iniciar sessão
  • /Identity/Conta/Terminar sessão
  • /Identity/Conta/Gerir

Aplicar migrações

Aplique as migrações para inicializar o banco de dados.

Execute o seguinte comando na Gestor de Pacotes Console (PMC):

Update-Database

Registo de Teste e Início de Sessão

Execute o aplicativo e registre um usuário. Dependendo do tamanho do ecrã, poderá ter de selecionar o botão de alternância de navegação para ver as ligações Registar e Iniciar sessão .

Ver a Identity base de dados

  • No menu View, selecione SQL Server Object Explorer (SSOX).
  • Navegue até (localdb)MSSQLLocalDB(SQL Server 13). Clique com o botão direito do rato em dbo.AspNetUsers>Ver Dados

Menu contextual na tabela AspNetUsers em SQL Server Object Explorer

Configurar Identity serviços

Os serviços são adicionados em Program.cs. O padrão típico é chamar métodos na seguinte ordem:

  1. Add{Service}
  2. builder.Services.Configure{Service}
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();

builder.Services.Configure<IdentityOptions>(options =>
{
    // Password settings.
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 1;

    // Lockout settings.
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;

    // User settings.
    options.User.AllowedUserNameCharacters =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
    options.User.RequireUniqueEmail = false;
});

builder.Services.ConfigureApplicationCookie(options =>
{
    // Cookie settings
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

    options.LoginPath = "/Identity/Account/Login";
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.SlidingExpiration = true;
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

O código precedente configura Identity com valores padrão de opção. Os serviços são disponibilizados para o aplicativo por meio de injeção de dependência.

Identity é ativado chamando UseAuthentication. UseAuthentication Adiciona middleware de autenticação ao pipeline de solicitação.

O aplicativo gerado por modelo não usa autorização. app.UseAuthorization está incluído para garantir que é adicionado na ordem correta caso o aplicativo adicione autorização. UseRouting, UseAuthenticatione UseAuthorization deve ser chamado na ordem indicada no código anterior.

Para obter mais informações sobre o IdentityOptions, consulte IdentityOptions e Arranque da Aplicação.

Modelar Registo, Iniciar Sessão, Terminar Sessão e Confirmação de Registo

Adicione os Registerficheiros , Login, LogOut, e RegisterConfirmation . Siga as instruções de Scaffold Identity em um projeto Razor com autorização para gerar o código mostrado nesta secção.

Examinar Registo

Quando um usuário clica no botão Registrar na Register página, a RegisterModel.OnPostAsync ação é invocada. O usuário é criado por CreateAsync(TUser) no _userManager objeto:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Desativar a verificação de conta padrão

Com os modelos padrão, o usuário é redirecionado para o Account.RegisterConfirmation local onde pode selecionar um link para ter a conta confirmada. O padrão Account.RegisterConfirmation é usado apenas para testes, a verificação automática de conta deve ser desabilitada em um aplicativo de produção.

Para exigir uma conta confirmada e impedir o login imediato no registro, defina DisplayConfirmAccountLink = false em /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs:

[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IEmailSender _sender;

    public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
    {
        _userManager = userManager;
        _sender = sender;
    }

    public string Email { get; set; }

    public bool DisplayConfirmAccountLink { get; set; }

    public string EmailConfirmationUrl { get; set; }

    public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
    {
        if (email == null)
        {
            return RedirectToPage("/Index");
        }

        var user = await _userManager.FindByEmailAsync(email);
        if (user == null)
        {
            return NotFound($"Unable to load user with email '{email}'.");
        }

        Email = email;
        // Once you add a real email sender, you should remove this code that lets you confirm the account
        DisplayConfirmAccountLink = false;
        if (DisplayConfirmAccountLink)
        {
            var userId = await _userManager.GetUserIdAsync(user);
            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            EmailConfirmationUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
                protocol: Request.Scheme);
        }

        return Page();
    }
}

Iniciar sessão

O formulário de login é exibido quando:

  • O link Entrar está selecionado.
  • Um utilizador tenta aceder a uma página restrita a que não está autorizado a aceder ou quando não está autenticado pelo sistema.

Quando o formulário na página de Login é enviado, a ação OnPostAsync é chamada. PasswordSignInAsync é chamado no objeto _signInManager.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Para informações sobre como tomar decisões de autorização, consulte Introdução à autorização em ASP.NET Core.

Terminar sessão

O link Sair invoca a LogoutModel.OnPost ação.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

No código anterior, o código return RedirectToPage(); precisa ser um redirecionamento para que o navegador execute uma nova solicitação e a identidade do usuário seja atualizada.

SignOutAsync Limpa as reivindicações do utilizador armazenadas num cookie.

O posto é especificado em Pages/Shared/_LoginPartial.cshtml:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Teste Identity

Os modelos padrão de project web permitem acesso anónimo às páginas iniciais. Para testar Identity, adicione [Authorize]:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Se tiver sessão iniciada, termine-a. Execute a aplicação e selecione a Privacy hiperligação. Você será redirecionado para a página de login.

Explorar Identity

Para explorar Identity mais detalhadamente:

Componentes do Identity

Todos os pacotes NuGet dependentes de Identity estão incluídos no framework partilhado ASP.NET Core.

O pacote principal para Identity é Microsoft.AspNetCore.Identity. Este pacote contém o conjunto central de interfaces para ASP.NET Core Identity, e está incluído por Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Migração para ASP.NET Core Identity

Para obter mais informações e orientações sobre como migrar o seu armazenamento existente Identity, consulte Migrar autenticação e Identity.

Definindo a força da senha

Consulte Configuração para obter um exemplo que define os requisitos mínimos de senha.

AddDefaultIdentity e AddIdentity

AddDefaultIdentity foi introduzido em ASP.NET Core 2.1. Chamar AddDefaultIdentity é semelhante a chamar o seguinte:

Consulte AddDefaultIdentity source para obter mais informações.

Impedir a publicação de ativos estáticos Identity

Para evitar publicar ativos estáticos Identity (folhas de estilo e ficheiros JavaScript para Identity UI) na raiz web, adicione a seguinte propriedade ResolveStaticWebAssetsInputsDependsOn e o alvo RemoveIdentityAssets ao ficheiro de projeto da aplicação.

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

Próximas Etapas

Por Rick Anderson

ASP.NET Core Identity:

  • É uma API que suporta a funcionalidade de login da interface do usuário (UI).
  • Gerencia usuários, senhas, dados de perfil, funções, declarações, tokens, confirmação de e-mail e muito mais.

Os utilizadores podem criar uma conta com as informações de login armazenadas em Identity ou podem usar um provedor de login externo. Os fornecedores de início de sessão externos suportados incluem o Facebook, o Google, a Conta Microsoft e o Twitter.

Para informações sobre como exigir autenticação para todos os utilizadores da aplicação, consulte Crie uma aplicação ASP.NET Core com dados de utilizador protegidos por autorização.

O código-fonte Identity está disponível em GitHub. Andaime Identity e exiba os arquivos gerados para revisar a interação do modelo com Identityo .

O Identity é normalmente configurado usando uma base de dados SQL Server para armazenar nomes de utilizador, palavras-passe e dados de perfil. Em alternativa, pode ser usado outro armazenamento persistente, por exemplo, o Armazenamento de Tabelas do Azure.

Neste tópico, você aprenderá a usar Identity para registrar, fazer login e logout de um usuário. Nota: os modelos tratam o nome de utilizador e o e-mail como o mesmo para os utilizadores. Para obter instruções mais detalhadas sobre como criar aplicações que usam Identity, consulte Próximas etapas.

plataforma de identidades da Microsoft é:

  • Uma evolução da plataforma de programadores Azure Active Directory (Azure AD).
  • Uma solução alternativa de identidade para autenticação e autorização em aplicações ASP.NET Core.
  • Não está relacionado com ASP.NET Core Identity.

ASP.NET Core Identity adiciona funcionalidade de login à interface de utilizador (UI) das aplicações web ASP.NET Core. Para proteger APIs da Web e SPAs, use uma das seguintes opções:

Duende IdentityServer é uma framework OpenID Connect e OAuth 2.0 para ASP.NET Core. O Duende IdentityServer habilita os seguintes recursos de segurança:

  • Autenticação como serviço (AaaS)
  • Logon único/desligamento (SSO) em vários tipos de aplicativos
  • controlo de acesso a APIs
  • Gateway de Federação

Para obter mais informações, consulte Visão geral do Duende IdentityServer.

Para mais informações sobre outros fornecedores de autenticação, consulte as opções de autenticação Community OSS para ASP.NET Core

Ver ou descarregar o código de exemplo (como descarregar).

Criar um aplicativo Web com autenticação

Crie um projeto de Aplicação Web ASP.NET Core com Contas de Utilizador Individuais.

  • Selecione File>Novo>Project.
  • Selecione ASP.NET Core Aplicação Web. Nomeie o projeto WebApp1 para que tenha o mesmo espaço de nomes do projeto de download. Clique em OK.
  • Selecione uma ASP.NET Core Aplicação Web, depois selecione Alterar Autenticação.
  • Selecione Contas de usuário individuais e clique em OK.

O projeto gerado fornece ASP.NET Core Identity como uma Razorbiblioteca de classes. A biblioteca de classes IdentityRazor expõe endpoints com a área Identity. Por exemplo:

  • /Identity/Conta/Iniciar sessão
  • /Identity/Conta/Terminar sessão
  • /Identity/Conta/Gerir

Aplicar migrações

Aplique as migrações para inicializar o banco de dados.

Execute o seguinte comando na Gestor de Pacotes Console (PMC):

PM> Update-Database

Registo de Teste e Início de Sessão

Execute o aplicativo e registre um usuário. Dependendo do tamanho do ecrã, poderá ter de selecionar o botão de alternância de navegação para ver as ligações Registar e Iniciar sessão .

Ver a Identity base de dados

  • No menu View, selecione SQL Server Object Explorer (SSOX).
  • Navegue até (localdb)MSSQLLocalDB(SQL Server 13). Clique com o botão direito do rato em dbo.AspNetUsers>Ver Dados

Menu contextual na tabela AspNetUsers em SQL Server Object Explorer

Configurar Identity serviços

Os serviços são adicionados em ConfigureServices. O padrão típico é chamar todos os Add{Service} métodos e, em seguida, chamar todos os services.Configure{Service} métodos.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
     // options.UseSqlite(
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();

    services.Configure<IdentityOptions>(options =>
    {
        // Password settings.
        options.Password.RequireDigit = true;
        options.Password.RequireLowercase = true;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireUppercase = true;
        options.Password.RequiredLength = 6;
        options.Password.RequiredUniqueChars = 1;

        // Lockout settings.
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.AllowedForNewUsers = true;

        // User settings.
        options.User.AllowedUserNameCharacters =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.User.RequireUniqueEmail = false;
    });

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Identity/Account/Login";
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        options.SlidingExpiration = true;
    });
}

O código realçado anterior configura Identity com valores de opção padrão. Os serviços são disponibilizados para o aplicativo por meio de injeção de dependência.

Identity é ativado chamando UseAuthentication. UseAuthentication Adiciona middleware de autenticação ao pipeline de solicitação.

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        // options.UseSqlite(
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();

    services.Configure<IdentityOptions>(options =>
    {
        // Password settings.
        options.Password.RequireDigit = true;
        options.Password.RequireLowercase = true;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireUppercase = true;
        options.Password.RequiredLength = 6;
        options.Password.RequiredUniqueChars = 1;

        // Lockout settings.
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.AllowedForNewUsers = true;

        // User settings.
        options.User.AllowedUserNameCharacters =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.User.RequireUniqueEmail = false;
    });

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Identity/Account/Login";
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        options.SlidingExpiration = true;
    });
}

O código precedente configura Identity com valores padrão de opção. Os serviços são disponibilizados para o aplicativo por meio de injeção de dependência.

Identity é ativado chamando UseAuthentication. UseAuthentication Adiciona middleware de autenticação ao pipeline de solicitação.

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

O aplicativo gerado por modelo não usa autorização. app.UseAuthorization está incluído para garantir que é adicionado na ordem correta caso o aplicativo adicione autorização. UseRouting, UseAuthentication, UseAuthorization, e UseEndpoints deve ser chamado na ordem mostrada no código anterior.

Para obter mais informações sobre IdentityOptions e Startup, consulte IdentityOptions e Inicialização do aplicativo.

Modelar Registo, Iniciar Sessão, Terminar Sessão e Confirmação de Registo

Adicione os Registerficheiros , Login, LogOut, e RegisterConfirmation . Siga as instruções de Scaffold Identity em um projeto Razor com autorização para gerar o código mostrado nesta secção.

Examinar Registo

Quando um usuário clica no botão Registrar na Register página, a RegisterModel.OnPostAsync ação é invocada. O usuário é criado por CreateAsync(TUser) no _userManager objeto:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Desativar a verificação de conta padrão

Com os modelos padrão, o usuário é redirecionado para o Account.RegisterConfirmation local onde pode selecionar um link para ter a conta confirmada. O padrão Account.RegisterConfirmation é usado apenas para testes, a verificação automática de conta deve ser desabilitada em um aplicativo de produção.

Para exigir uma conta confirmada e impedir o login imediato no registro, defina DisplayConfirmAccountLink = false em /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs:

[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IEmailSender _sender;

    public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
    {
        _userManager = userManager;
        _sender = sender;
    }

    public string Email { get; set; }

    public bool DisplayConfirmAccountLink { get; set; }

    public string EmailConfirmationUrl { get; set; }

    public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
    {
        if (email == null)
        {
            return RedirectToPage("/Index");
        }

        var user = await _userManager.FindByEmailAsync(email);
        if (user == null)
        {
            return NotFound($"Unable to load user with email '{email}'.");
        }

        Email = email;
        // Once you add a real email sender, you should remove this code that lets you confirm the account
        DisplayConfirmAccountLink = false;
        if (DisplayConfirmAccountLink)
        {
            var userId = await _userManager.GetUserIdAsync(user);
            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            EmailConfirmationUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
                protocol: Request.Scheme);
        }

        return Page();
    }
}

Iniciar sessão

O formulário de login é exibido quando:

  • O link Entrar está selecionado.
  • Um utilizador tenta aceder a uma página restrita a que não está autorizado a aceder ou quando não está autenticado pelo sistema.

Quando o formulário na página de Login é enviado, a ação OnPostAsync é chamada. PasswordSignInAsync é chamado no objeto _signInManager.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Para informações sobre como tomar decisões de autorização, consulte Introdução à autorização em ASP.NET Core.

Terminar sessão

O link Sair invoca a LogoutModel.OnPost ação.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

No código anterior, o código return RedirectToPage(); precisa ser um redirecionamento para que o navegador execute uma nova solicitação e a identidade do usuário seja atualizada.

SignOutAsync Limpa as reivindicações do utilizador armazenadas num cookie.

O posto é especificado em Pages/Shared/_LoginPartial.cshtml:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Teste Identity

Os modelos padrão de project web permitem acesso anónimo às páginas iniciais. Para testar Identity, adicione [Authorize]:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Se tiver sessão iniciada, termine-a. Execute a aplicação e selecione a Privacy hiperligação. Você será redirecionado para a página de login.

Explorar Identity

Para explorar Identity mais detalhadamente:

Componentes do Identity

Todos os pacotes NuGet dependentes de Identity estão incluídos no framework partilhado ASP.NET Core.

O pacote principal para Identity é Microsoft.AspNetCore.Identity. Este pacote contém o conjunto central de interfaces para ASP.NET Core Identity, e está incluído por Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Migração para ASP.NET Core Identity

Para obter mais informações e orientações sobre como migrar o seu armazenamento existente Identity, consulte Migrar autenticação e Identity.

Definindo a força da senha

Consulte Configuração para obter um exemplo que define os requisitos mínimos de senha.

Impedir a publicação de ativos estáticos Identity

Para evitar publicar ativos estáticos Identity (folhas de estilo e ficheiros JavaScript para Identity UI) na raiz web, adicione a seguinte propriedade ResolveStaticWebAssetsInputsDependsOn e o alvo RemoveIdentityAssets ao ficheiro de projeto da aplicação.

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

Próximas Etapas