De Rick Anderson
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.
ASP.NET Core não está relacionado à plataforma de identidade da Microsoft. A plataforma de identidade da Microsoft é:
- Uma evolução da plataforma de desenvolvedor do Azure Active Directory (Azure AD).
- Uma solução de identidade 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:
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
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.
dotnet new webapp --auth Individual -o WebApp1
O comando anterior cria um aplicativo Web Razor usando o SQLite. Para criar aplicativos Web com LocalDB, execute o seguinte comando:
dotnet new webapp --auth Individual -uld -o WebApp1
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
Aplique as migrações para inicializar o banco de dados.
Execute o seguinte comando no Console do Gerenciador de Pacotes (PMC):
Update-Database
As migrações não são necessárias nesta etapa quando você usa o SQLite.
Se dotnet ef
não tiver sido instalado, instale-o como uma ferramenta global:
dotnet tool install --global dotnet-ef
Para obter mais informações sobre a CLI para EF Core, consulte EF Core referência de ferramentas para a CLI do .NET.
Para o LocalDB, execute o seguinte comando:
dotnet ef database update
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:

Há muitas ferramentas de terceiros que você pode baixar para gerenciar e exibir um banco de dados SQLite, por exemplo, Navegador do DB para SQLite.
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
Se você criou o projeto com o nome WebApp1 e não estiver usando o SQLite, execute os seguintes comandos. Caso contrário, use o namespace correto para ApplicationDbContext
:
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet aspnet-codegenerator identity -dc WebApp1.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.Logout;Account.RegisterConfirmation"
Ao usar o SQLite, acrescente --useSqLite
ou -sqlite
:
dotnet aspnet-codegenerator identity -dc WebApp1.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.Logout;Account.RegisterConfirmation" --useSqLite
O PowerShell usa ponto e vírgula como separador de comandos. Quando você estiver usando o PowerShell, faça o escape dos pontos e vírgulas na lista de arquivos ou coloque a lista de arquivos entre aspas duplas, como mostra o exemplo anterior.
Para obter mais informações sobre scaffolding Identity, confira Identidade de Scaffold em um projeto Razor com autorização.
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();
}
}
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.
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 execute uma nova solicitação e a identidade 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>
Os modelos de projeto 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 estiver conectado, desconecte-se. Execute o aplicativo e selecione o link Privacy. Você é redirecionado à página de logon.
Para explorar Identity em mais detalhes:
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>
De Rick Anderson
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.
plataforma de identidade da Microsoft é:
- Uma evolução da plataforma de desenvolvedor do Azure Active Directory (Azure AD).
- Uma solução de identidade 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:
O Duende IdentityServer é uma estrutura do OpenID Connect e OAuth 2.0 para ASP.NET Core. O IdentityServer da Duende 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 obter mais informações, consulte Visão geral do IdentityServer da Duende.
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.
dotnet new webapp --auth Individual -o WebApp1
O comando anterior cria um aplicativo Web Razor usando o SQLite. Para criar aplicativos Web com LocalDB, execute o seguinte comando:
dotnet new webapp --auth Individual -uld -o WebApp1
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
Aplique as migrações para inicializar o banco de dados.
Execute o seguinte comando no Console do Gerenciador de Pacotes (PMC):
PM> Update-Database
As migrações não são necessárias nesta etapa quando você usa o SQLite.
Se dotnet ef
não tiver sido instalado, instale-o como uma ferramenta global:
dotnet tool install --global dotnet-ef
Para obter mais informações sobre a CLI para EF Core, consulte EF Core referência de ferramentas para a CLI do .NET.
Para o LocalDB, execute o seguinte comando:
dotnet ef database update
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:

Há muitas ferramentas de terceiros que você pode baixar para gerenciar e exibir um banco de dados SQLite, por exemplo, Navegador do DB para SQLite.
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
Se você criou o projeto com o nome WebApp1 e não estiver usando o SQLite, execute os seguintes comandos. Caso contrário, use o namespace correto para ApplicationDbContext
:
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet aspnet-codegenerator identity -dc WebApp1.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.Logout;Account.RegisterConfirmation"
Ao usar o SQLite, acrescente --useSqLite
ou -sqlite
:
dotnet aspnet-codegenerator identity -dc WebApp1.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.Logout;Account.RegisterConfirmation" --useSqLite
O PowerShell usa ponto e vírgula como separador de comandos. Quando você estiver usando o PowerShell, faça o escape dos pontos e vírgulas na lista de arquivos ou coloque a lista de arquivos entre aspas duplas, como mostra o exemplo anterior.
Para obter mais informações sobre scaffolding Identity, confira Identidade de Scaffold em um projeto Razor com autorização.
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();
}
}
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.
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 execute uma nova solicitação e a identidade 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>
Os modelos de projeto 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 estiver conectado, desconecte-se. Execute o aplicativo e selecione o link Privacy. Você é redirecionado à página de logon.
Para explorar Identity em mais detalhes:
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>