Partilhar via


Introdução ao Identity no ASP.NET Core

ASP.NET Núcleo 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 obter informações sobre como exigir globalmente que todos os usuários sejam autenticados, consulte Exigir usuários autenticados.

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

Identity normalmente é configurado usando um banco de dados do SQL Server para armazenar nomes de usuário, senhas e dados de perfil. Como alternativa, outro repositório persistente pode ser usado, por exemplo, o Armazenamento de Tabela 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 obter mais informações sobre Identity em Blazor aplicativos, consulte Autenticação e autorização ASP.NET Core Blazor e os artigos que se seguem na Blazor documentação.

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

  • Uma evolução da plataforma de desenvolvedor do Azure Ative Directory (Azure AD).
  • Uma solução de identidade alternativa para autenticação e autorização em aplicativos ASP.NET Core.

O ASP.NET Core Identity adiciona a funcionalidade de login da interface do usuário (UI) aos aplicativos Web ASP.NET Core. Para proteger APIs da Web e SPAs, use uma das seguintes opções:

O Duende Identity Server é uma framework para OpenID Connect e OAuth 2.0 no 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
  • Controle de acesso para APIs
  • Gateway de Federação

Important

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

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

Visualize ou baixe o código de exemplo (como fazer o download).

Crie um Blazor Web App com autenticação

Crie um projeto ASP.NET Core Blazor Web App 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 IdentityRazor componentes. Os componentes são encontrados na Components/Account pasta do projeto de 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 se gera um Blazor Web App com Contas Individuais, os componentes IdentityRazor são incluídos no projeto gerado. Os IdentityRazor componentes também podem ser inspecionados na Components/Account pasta do projeto do servidor no Blazor Web App modelo de projeto (dotnet/aspnetcorerepositório GitHub).

Note

Os links de documentação para a fonte de referência do .NET geralmente 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 obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Para obter mais informações, consulte Autenticação e autorização ASP.NET Core Blazor e os artigos que a seguem na Blazor documentação. A maioria dos artigos na área Segurança e Identity do conjunto de documentação principal do ASP.NET Core aplica-se a Blazor aplicações. 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 de documentação geral do ASP.NET Core, seguido de aceder aos artigos na documentação de Segurança Blazor e Identity.

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

Crie um projeto ASP.NET Core Web Application (Razor Pages) com Contas Individuais.

  • Selecione o modelo ASP.NET Core Web App (Razor Pages ). 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 Razor classes (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 na RCL, consulte a fonte de referência ASP.NET Core (dotnet/aspnetcorerepositório GitHub, Identity/UI/src/Areas/Identity/Pages pasta). Você pode estruturar páginas individuais ou todas as páginas no app. Para obter mais informações, consulte Scaffold Identity em projetos ASP.NET Core.

Criar um aplicativo MVC com autenticação

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

  • Selecione o modelo ASP.NET Core Web App (Model-View-Controller ). 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 Razor classes (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 na RCL, consulte a fonte de referência ASP.NET Core (dotnet/aspnetcorerepositório GitHub, Identity/UI/src/Areas/Identity/Pages pasta). Você pode estruturar páginas individuais ou todas as páginas no app. Para obter 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 no Console do Gerenciador de Pacotes (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 Exibir , selecione Pesquisador de Objetos do SQL Server (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 no Pesquisador de Objetos do SQL Server

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.

ASP.NET Principais Identity métricas

ASP.NET métricas principais Identity fornecem recursos de monitoramento para processos de autenticação e gerenciamento de usuários. 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 obter detalhes completos sobre as métricas disponíveis e como usá-las, consulte ASP.NET Métricas principais.

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

Adicione os Registerficheiros , Login, LogOut, e RegisterConfirmation . Siga as instruções para adicionar a identidade Scaffold num projeto 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 foi 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 obter informações sobre como tomar decisões de autorização, consulte Introdução à autorização no 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 de projeto da Web padrão permitem acesso anônimo às home pages. 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:

Identity Componentes

Todos os Identitypacotes NuGet dependentes estão incluídos na estrutura compartilhada do ASP.NET Core.

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

Migrando para o 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 no ASP.NET Core 2.1. Chamar AddDefaultIdentity é semelhante a chamar o seguinte:

Consulte fonte AddDefaultIdentity para obter mais informações.

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

Para evitar a publicação de ativos estáticos Identity (folhas de estilo e arquivos JavaScript para Identity interface do usuário) na raiz da Web, adicione a seguinte ResolveStaticWebAssetsInputsDependsOn propriedade e RemoveIdentityAssets destino ao arquivo de projeto do aplicativo:

<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 Núcleo 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 obter informações sobre como exigir globalmente que todos os usuários sejam autenticados, consulte Exigir usuários autenticados.

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

Identity normalmente é configurado usando um banco de dados do SQL Server para armazenar nomes de usuário, senhas e dados de perfil. Como alternativa, outro repositório persistente pode ser usado, por exemplo, o Armazenamento de Tabela 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 à plataforma de identidade da Microsoft. A plataforma de identidade da Microsoft é:

  • Uma evolução da plataforma de desenvolvedor do Azure Ative Directory (Azure AD).
  • Uma solução de identidade alternativa para autenticação e autorização em aplicativos ASP.NET Core.

O ASP.NET Core Identity adiciona a funcionalidade de login da interface do usuário (UI) aos aplicativos Web ASP.NET Core. Para proteger APIs da Web e SPAs, use uma das seguintes opções:

O Duende Identity Server é uma framework para OpenID Connect e OAuth 2.0 no 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
  • Controle de acesso para APIs
  • Gateway de Federação

Important

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

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

Visualize ou baixe o código de exemplo (como fazer o download).

Criar um aplicativo Web com autenticação

Crie um projeto de aplicativo Web principal ASP.NET com contas de usuário individuais.

  • Selecione o modelo ASP.NET Core Web App. Nomeie o projeto WebApp1 para ter o mesmo namespace que o download do projeto. 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 biblioteca de Razor classes. A biblioteca de classes IdentityRazor expõe endpoints com a área Identity. Por exemplo:

  • /Identity/Conta/Login
  • /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 no Console do Gerenciador de Pacotes (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 Exibir , selecione Pesquisador de Objetos do SQL Server (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 no Pesquisador de Objetos do SQL Server

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 para adicionar a identidade Scaffold num projeto 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 foi 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 obter informações sobre como tomar decisões de autorização, consulte Introdução à autorização no 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 de projeto da Web padrão permitem acesso anônimo às home pages. 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:

Identity Componentes

Todos os Identitypacotes NuGet dependentes estão incluídos na estrutura compartilhada do ASP.NET Core.

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

Migrando para o 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 no ASP.NET Core 2.1. Chamar AddDefaultIdentity é semelhante a chamar o seguinte:

Consulte fonte AddDefaultIdentity para obter mais informações.

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

Para evitar a publicação de ativos estáticos Identity (folhas de estilo e arquivos JavaScript para Identity interface do usuário) na raiz da Web, adicione a seguinte ResolveStaticWebAssetsInputsDependsOn propriedade e RemoveIdentityAssets destino ao arquivo de projeto do aplicativo:

<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 Núcleo 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 obter informações sobre como exigir globalmente que todos os usuários sejam autenticados, consulte Exigir usuários autenticados.

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

Identity normalmente é configurado usando um banco de dados do SQL Server para armazenar nomes de usuário, senhas e dados de perfil. Como alternativa, outro repositório persistente pode ser usado, por exemplo, o Armazenamento de Tabela 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.

A plataforma de identidade da Microsoft é:

  • Uma evolução da plataforma de desenvolvedor do Azure Ative Directory (Azure AD).
  • Uma solução de identidade alternativa para autenticação e autorização em aplicativos ASP.NET Core.
  • Não relacionado com ASP.NET Core Identity.

O ASP.NET Core Identity adiciona a funcionalidade de login da interface do usuário (UI) aos aplicativos Web ASP.NET Core. Para proteger APIs da Web e SPAs, use uma das seguintes opções:

Duende IdentityServer é uma estrutura 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
  • Controle de acesso para APIs
  • Gateway de Federação

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

Para obter mais informações sobre outros provedores de autenticação, consulte Opções de autenticação OSS da comunidade para ASP.NET Core

Visualize ou baixe o código de exemplo (como fazer o download).

Criar um aplicativo Web com autenticação

Crie um projeto de aplicativo Web principal ASP.NET com contas de usuário individuais.

  • Selecione Arquivo>Novo>Projeto.
  • Selecione Aplicação Web ASP.NET Core. Nomeie o projeto WebApp1 para ter o mesmo namespace que o download do projeto. Clique em OK.
  • Selecione um ASP.NET Aplicativo Web Principal e, em seguida, selecione Alterar Autenticação.
  • Selecione Contas de usuário individuais e clique em OK.

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

  • /Identity/Conta/Login
  • /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 no Console do Gerenciador de Pacotes (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 Exibir , selecione Pesquisador de Objetos do SQL Server (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 no Pesquisador de Objetos do SQL Server

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 para adicionar a identidade Scaffold num projeto 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 foi 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 obter informações sobre como tomar decisões de autorização, consulte Introdução à autorização no 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 de projeto da Web padrão permitem acesso anônimo às home pages. 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:

Identity Componentes

Todos os Identitypacotes NuGet dependentes estão incluídos na estrutura compartilhada do ASP.NET Core.

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

Migrando para o 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 a publicação de ativos estáticos Identity (folhas de estilo e arquivos JavaScript para Identity interface do usuário) na raiz da Web, adicione a seguinte ResolveStaticWebAssetsInputsDependsOn propriedade e RemoveIdentityAssets destino ao arquivo de projeto do aplicativo:

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

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

Próximas Etapas