Introdução ao Identity no ASP.NET Core
ASP.NET Core Identity:
- É uma API que suporta a funcionalidade de logon da interface do usuário (UI).
- Gerencia usuários, senhas, dados de perfil, funções, declarações, tokens, confirmação por email e muito mais.
Os usuários podem criar uma conta com as informações de logon armazenadas em Identity ou podem usar um provedor de logon externo. Os provedores de logon externo suportados incluem Facebook, Google, conta Microsoft e Twitter.
Para obter informações sobre como exigir que todos os usuários sejam autenticados globalmente, confira Exigir usuários autenticados.
O código-fonte Identity está disponível no GitHub. Faça Scaffold Identity e exiba os arquivos gerados para analisar a interação do modelo com Identity.
Normalmente, o Identity é configurado usando um banco de dados do SQL Server para armazenar nomes de usuários, senhas e dados de perfil. Como alternativa, você pode usar outro armazenamento persistente, por exemplo, o Armazenamento de Tabelas do Azure.
Neste tópico, você aprenderá a usar Identity para registrar, fazer o logon e fazer o logoff de um usuário. Observação: os modelos tratam o nome de usuário e o email como os mesmos para os usuários. Para obter instruções mais detalhadas sobre como criar aplicativos que usam Identity, confira Próximas Etapas.
A Identity do ASP.NET Core não está relacionada à plataforma de identity da Microsoft. A plataforma de identity da Microsoft é:
- Uma evolução da plataforma de desenvolvedor do Azure Active Directory (Azure AD).
- Uma solução de identity alternativa para autenticação e autorização em aplicativos do ASP.NET Core.
O ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos aplicativos Web do ASP.NET Core. Para proteger APIs Web e SPAs, use uma das seguintes opções:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
O Duende Identity Server é uma estrutura do OpenID Connect e OAuth 2.0 para ASP.NET Core. O Duende Identity Server habilita os seguintes recursos de segurança:
- AaaS (autenticação como serviço)
- SSO (logon único) em vários tipos de aplicativo
- Controle de acesso para APIs
- Federation Gateway
Importante
O Software Duende pode exigir que você pague uma taxa de licença pelo uso de produção do Duende Identity Server. Para obter mais informações, consulte Migrar do ASP.NET Core 5.0 para o 6.0.
Para obter mais informações, confira a documentação do Duende Identity Server (site da Duende Software).
Exiba ou faça download do código de exemplo (como fazer download).
Criar um aplicativo Web com autenticação
Crie um projeto de aplicativo Web ASP.NET Core com contas de usuário individuais.
- Selecione o modelo Aplicativo Web ASP.NET Core. Dê ao projeto o nome WebApp1 para que ele tenha o mesmo namespace que o download do projeto. Clique no OK.
- Na entrada de Tipo de autenticação, selecione Contas de Usuário Individuais.
O projeto gerado fornece o ASP.NET Core Identity como uma biblioteca de classes do Razor. A biblioteca de classes IdentityRazor expõe os pontos de extremidade com a área Identity
. Por exemplo:
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
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
Registro de teste e logon
Execute o aplicativo e registre um usuário. Dependendo do tamanho da tela, talvez você precise selecionar o botão de alternância de navegação para conferir os links Registrar e Logon.
Exibição do banco de dados Identity
- No menu Exibir, selecione Pesquisador de Objetos do Servidor SQL. (SSOX).
- Navegue até (localdb)MSSQLLocalDB(SQL Server 13). Clique com o botão direito do mouse em dbo.AspNetUsers>Dados de Exibição:
Configurar os serviços Identity
Os serviços foram adicionados em Program.cs
. O padrão típico é chamar os métodos na seguinte ordem:
Add{Service}
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 anterior configura Identity com valores da opção padrão. Os serviços são disponibilizados para o aplicativo por meio da injeção de dependência.
Identity é habilitado quando você chama UseAuthentication. UseAuthentication
adiciona autenticação Middleware ao pipeline de solicitações.
O aplicativo gerado pelo modelo não usa a autorização. app.UseAuthorization
é incluído para que você certifique-se de que ele seja adicionado na ordem correta caso o aplicativo adicione uma autorização. UseRouting
, UseAuthentication
e UseAuthorization
devem ser chamados na ordem mostrada no código anterior.
Para obter mais informações sobre IdentityOptions
, confira IdentityOptions e a Inicialização do aplicativo.
Registro de Scaffold, Logon, Logoff e ConfirmaçãoDeRegistro
Adicione os arquivos Register
, Login
, LogOut
e RegisterConfirmation
. Siga as instruções identity do Scaffold em um projeto do Razor com autorização para gerar o código mostrado nesta seção.
Examinar o Registro
Quando um usuário clica no botão Registrar na página Register
, a ação RegisterModel.OnPostAsync
é chamada. O usuário foi criado por CreateAsync(TUser) no objeto _userManager
:
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();
}
Para desabilitar a verificação padrão da conta
Com os modelos padrão, o usuário é redirecionado para Account.RegisterConfirmation
, no qual pode selecionar um link para confirmar a conta. O padrão Account.RegisterConfirmation
é usado apenas para teste. A verificação automática de conta deve ser desabilitada em um aplicativo de produção.
Para exigir uma conta confirmada e impedir o logon 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();
}
}
Fazer logon
O formulário de Logon é exibido quando:
- O link Logon é selecionado.
- Um usuário tenta acessar uma página restrita que não está autorizado a acessar ou quando não tiver sido autenticado pelo sistema.
Quando o formulário da página de logon é enviado, a ação OnPostAsync
é chamada. PasswordSignInAsync
é chamada 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 sobre autorização, confira Introdução à autorização no ASP.NET Core.
Faça logoff
O link de Logoff invoca a ação LogoutModel.OnPost
.
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 realize uma nova solicitação e a identity do usuário seja atualizada.
SignOutAsync limpa as declarações do usuário armazenadas em cookie.
A postagem é especificada 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 projetos Web permitem o 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 estiver conectado, desconecte-se. Execute o aplicativo e selecione o link Privacy. Você é redirecionado à página de logon.
Explorar Identity
Para explorar Identity em mais detalhes:
- Criar fonte de interface do usuário de identity completa
- Examine o código-fonte de cada página e percorra o depurador.
Identity Componentes
Todos os pacotes NuGet dependentes de Identity estão incluídos na estrutura compartilhada do ASP.NET Core.
O principal pacote para Identity é Microsoft.AspNetCore.Identity. Esse pacote contém o principal conjunto de interfaces para o ASP.NET Core Identity e é incluído por Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migrando para o ASP.NET Core Identity
Para obter mais informações e diretrizes sobre como migrar o armazenamento existente Identity, confira Migrar a autenticação e Identity.
Como definir a força da senha
Confira a Configuração para ver 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:
Para obter mais informações, consulte Fonte AddDefaultIdentity.
Impedir a publicação de ativos estáticos do Identity
Para impedir a publicação de ativos estáticos Identity (folhas de estilo e arquivos JavaScript para a interface do usuário Identity) na raiz da Web, adicione a seguinte propriedade ResolveStaticWebAssetsInputsDependsOn
e destino RemoveIdentityAssets
ao arquivo do 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
- Confira esta edição do GitHub para obter informações sobre como configurar Identity usando o SQLite.
- Configurar Identity
- Criar um aplicativo ASP.NET Core com os dados do usuário protegidos por autorização
- Adicione, baixe e exclua dados do usuário para Identity em um projeto ASP.NET Core
- Habilitar a geração de código QR para aplicativos de autenticador TOTP no ASP.NET Core
- Migrar a autenticação e Identity para o ASP.NET Core
- Confirmação de conta e de recuperação de senha no ASP.NET Core
- Autenticação de dois fatores com SMS no ASP.NET Core
- Hospede o ASP.NET Core em um Web Farm
ASP.NET Core Identity:
- É uma API que suporta a funcionalidade de logon da interface do usuário (UI).
- Gerencia usuários, senhas, dados de perfil, funções, declarações, tokens, confirmação por email e muito mais.
Os usuários podem criar uma conta com as informações de logon armazenadas em Identity ou podem usar um provedor de logon externo. Os provedores de logon externo suportados incluem Facebook, Google, conta Microsoft e Twitter.
Para obter informações sobre como exigir que todos os usuários sejam autenticados globalmente, confira Exigir usuários autenticados.
O código-fonte Identity está disponível no GitHub. Faça Scaffold Identity e exiba os arquivos gerados para analisar a interação do modelo com Identity.
Normalmente, o Identity é configurado usando um banco de dados do SQL Server para armazenar nomes de usuários, senhas e dados de perfil. Como alternativa, você pode usar outro armazenamento persistente, por exemplo, o Armazenamento de Tabelas do Azure.
Neste tópico, você aprenderá a usar Identity para registrar, fazer o logon e fazer o logoff de um usuário. Observação: os modelos tratam o nome de usuário e o email como os mesmos para os usuários. Para obter instruções mais detalhadas sobre como criar aplicativos que usam Identity, confira Próximas Etapas.
A plataforma de identity da Microsoft é:
- Uma evolução da plataforma de desenvolvedor do Azure Active Directory (Azure AD).
- Uma solução de identity alternativa para autenticação e autorização em aplicativos do ASP.NET Core.
- Não está relacionado ao ASP.NET Core Identity.
O ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos aplicativos Web do ASP.NET Core. Para proteger APIs Web e SPAs, use uma das seguintes opções:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende IdentityServer. O Duende IdentityServer é um produto de terceiros.
O Duende IdentityServer é uma estrutura do OpenID Connect e do OAuth 2.0 para ASP.NET Core. O Duende IdentityServer habilita os seguintes recursos de segurança:
- AaaS (autenticação como serviço)
- SSO (logon único) em vários tipos de aplicativo
- Controle de acesso para APIs
- Federation Gateway
Para mais informações, confira Visão geral do Duende IdentityServer.
Para obter mais informações sobre outros provedores de autenticação, consulte Opções de autenticação de OSS da comunidade para ASP.NET Core
Exiba ou faça download do código de exemplo (como fazer download).
Criar um aplicativo Web com autenticação
Crie um projeto de aplicativo Web ASP.NET Core com contas de usuário individuais.
- Selecione Arquivo>Novo>Projeto.
- Selecione Aplicativo Web ASP.NET Core. Dê ao projeto o nome WebApp1 para que ele tenha o mesmo namespace que o download do projeto. Clique no OK.
- Selecione um aplicativo Web ASP.NET Core e, em seguida, selecione Alterar autenticação.
- Selecione Contas de usuário individuais e clique em OK.
O projeto gerado fornece o ASP.NET Core Identity como uma biblioteca de classes do Razor. A biblioteca de classes IdentityRazor expõe os pontos de extremidade com a área Identity
. Por exemplo:
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
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
Registro de teste e logon
Execute o aplicativo e registre um usuário. Dependendo do tamanho da tela, talvez você precise selecionar o botão de alternância de navegação para conferir os links Registrar e Logon.
Exibição do banco de dados Identity
- No menu Exibir, selecione Pesquisador de Objetos do Servidor SQL. (SSOX).
- Navegue até (localdb)MSSQLLocalDB(SQL Server 13). Clique com o botão direito do mouse em dbo.AspNetUsers>Dados de Exibição:
Configurar os serviços Identity
Os serviços foram adicionados em ConfigureServices
. O padrão típico consiste em chamar todos os métodos Add{Service}
e, em seguida, chamar todos os métodos services.Configure{Service}
.
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 destacado anteriormente configura Identity com valores de opção padrão. Os serviços são disponibilizados para o aplicativo por meio da injeção de dependência.
Identity é habilitado quando você chama UseAuthentication. UseAuthentication
adiciona autenticação Middleware ao pipeline de solicitações.
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 anterior configura Identity com valores da opção padrão. Os serviços são disponibilizados para o aplicativo por meio da injeção de dependência.
Identity é habilitado quando você chama UseAuthentication. UseAuthentication
adiciona autenticação Middleware ao pipeline de solicitações.
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 pelo modelo não usa a autorização. app.UseAuthorization
é incluído para que você certifique-se de que ele seja adicionado na ordem correta caso o aplicativo adicione uma autorização. UseRouting
, UseAuthentication
, UseAuthorization
e UseEndpoints
devem ser chamados na ordem mostrada no código anterior.
Para obter mais informações sobre IdentityOptions
e Startup
, confira IdentityOptions e Inicialização do aplicativo.
Registro de Scaffold, Logon, Logoff e ConfirmaçãoDeRegistro
Adicione os arquivos Register
, Login
, LogOut
e RegisterConfirmation
. Siga as instruções identity do Scaffold em um projeto do Razor com autorização para gerar o código mostrado nesta seção.
Examinar o Registro
Quando um usuário clica no botão Registrar na página Register
, a ação RegisterModel.OnPostAsync
é chamada. O usuário foi criado por CreateAsync(TUser) no objeto _userManager
:
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();
}
Para desabilitar a verificação padrão da conta
Com os modelos padrão, o usuário é redirecionado para Account.RegisterConfirmation
, no qual pode selecionar um link para confirmar a conta. O padrão Account.RegisterConfirmation
é usado apenas para teste. A verificação automática de conta deve ser desabilitada em um aplicativo de produção.
Para exigir uma conta confirmada e impedir o logon 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();
}
}
Fazer logon
O formulário de Logon é exibido quando:
- O link Logon é selecionado.
- Um usuário tenta acessar uma página restrita que não está autorizado a acessar ou quando não tiver sido autenticado pelo sistema.
Quando o formulário da página de logon é enviado, a ação OnPostAsync
é chamada. PasswordSignInAsync
é chamada 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 sobre autorização, confira Introdução à autorização no ASP.NET Core.
Faça logoff
O link de Logoff invoca a ação LogoutModel.OnPost
.
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 realize uma nova solicitação e a identity do usuário seja atualizada.
SignOutAsync limpa as declarações do usuário armazenadas em cookie.
A postagem é especificada 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 projetos Web permitem o 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 estiver conectado, desconecte-se. Execute o aplicativo e selecione o link Privacy. Você é redirecionado à página de logon.
Explorar Identity
Para explorar Identity em mais detalhes:
- Criar fonte de interface do usuário de identity completa
- Examine o código-fonte de cada página e percorra o depurador.
Identity Componentes
Todos os pacotes NuGet dependentes de Identity estão incluídos na estrutura compartilhada do ASP.NET Core.
O principal pacote para Identity é Microsoft.AspNetCore.Identity. Esse pacote contém o principal conjunto de interfaces para o ASP.NET Core Identity e é incluído por Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migrando para o ASP.NET Core Identity
Para obter mais informações e diretrizes sobre como migrar o armazenamento existente Identity, confira Migrar a autenticação e Identity.
Como definir a força da senha
Confira a Configuração para ver um exemplo que define os requisitos mínimos de senha.
Impedir a publicação de ativos estáticos do Identity
Para impedir a publicação de ativos estáticos Identity (folhas de estilo e arquivos JavaScript para a interface do usuário Identity) na raiz da Web, adicione a seguinte propriedade ResolveStaticWebAssetsInputsDependsOn
e destino RemoveIdentityAssets
ao arquivo do 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
- ASP.NET Core Identity código-fonte
- Fonte AddDefaultIdentity
- Confira esta edição do GitHub para obter informações sobre como configurar Identity usando o SQLite.
- Configurar Identity
- Criar um aplicativo ASP.NET Core com os dados do usuário protegidos por autorização
- Adicione, baixe e exclua dados do usuário para Identity em um projeto ASP.NET Core
- Habilitar a geração de código QR para aplicativos de autenticador TOTP no ASP.NET Core
- Migrar a autenticação e Identity para o ASP.NET Core
- Confirmação de conta e de recuperação de senha no ASP.NET Core
- Autenticação de dois fatores com SMS no ASP.NET Core
- Hospede o ASP.NET Core em um Web Farm