Introdução ao Identity no ASP.NET Core

De Rick Anderson

ASP.NET Core Identity:

  • É uma API que dá suporte à funcionalidade de logon da interface do usuário.
  • 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 no Identity ou podem usar um provedor de logon externo. Os provedores de logon externo com suporte incluem o Facebook, o Google, a conta da 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 em github. Scaffold Identity e exiba os arquivos gerados para revisar a interação do modelo com o Identity .

Identitynormalmente, o é configurado usando um banco de dados SQL Server para armazenar nomes de usuário, senhas e de perfil. como alternativa, outro armazenamento persistente pode ser usado, por exemplo, a tabela do Azure Armazenamento.

Neste tópico, você aprenderá a usar o Identity para registrar, fazer logon e fazer logoff de um usuário. Observação: os modelos tratam o nome de usuário e o email como o mesmo para os usuários. Para obter instruções mais detalhadas sobre como criar aplicativos que usam o Identity , consulte próximas etapas.

plataforma de identidade da Microsoft é:

  • uma evolução da plataforma de desenvolvedor do Azure Active Directory (AD do Azure).
  • Não relacionado a ASP.NET Core Identity .

ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos ASP.NET Web Core. Para proteger APIs Web e SPAs, use um dos seguintes:

IdentityServer4 é uma estrutura OpenID Connect e OAuth 2.0 para ASP.NET Core. IdentityO Server4 habilita os seguintes recursos de segurança:

  • Autenticação como serviço (AaaS)
  • SSO (single sign-on/off) em vários tipos de aplicativos
  • Controle de acesso para APIs
  • Gateway de Federação

Para obter mais informações, consulte Bem-vindo ao Identity Server4.

Exiba ou baixe o código de exemplo (como baixar).

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 de aplicativo Web ASP.NET Core . Nomeie o projeto WebApp1 para ter o mesmo namespace do 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 Razor biblioteca de classes. A Identity Razor biblioteca de classes expõe pontos de extremidade com a Identity área. 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

Teste de registro e logon

Execute o aplicativo e registre um usuário. Dependendo do tamanho da tela, talvez seja necessário selecionar o botão de alternância de navegação para ver os links de registro e logon .

Exibir o banco de Identity 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 mouse em dbo. Dados de exibição do AspNetUsers > :

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. 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 Identity é configurado 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 é habilitado chamando UseAuthentication. UseAuthentication Adiciona o 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 ele seja adicionado na ordem correta caso o aplicativo adicione autorização. UseRouting, UseAuthentication , UseAuthorization e UseEndpoints devem ser chamados na ordem mostrada no código anterior.

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

Scaffold registro, logon, LogOut e RegisterConfirmation

Adicione os Register Login arquivos,, LogOut e RegisterConfirmation . Siga a identidade do Scaffold em um Razor projeto com instruções de autorização para gerar o código mostrado nesta seção.

Examinar registro

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 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();
}

Desabilitar verificação de conta padrão

Com os modelos padrão, o usuário é redirecionado para o Account.RegisterConfirmation onde ele pode selecionar um link para que a conta seja confirmada. O padrão Account.RegisterConfirmation é usado somente 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 está selecionado.
  • Um usuário tenta acessar uma página restrita que não tem autorização para acessar ou quando elas não foram autenticadas pelo sistema.

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

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 .

Faça logoff

O link fazer logoff 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 declarações do usuário armazenadas em um cookie .

Post é especificado nas páginas/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>

Testar Identity

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 você estiver conectado, saia. Execute o aplicativo e selecione o Privacy link. Você é redirecionado à página de logon.

Apresenta Identity

Para explorar Identity mais detalhadamente:

Identity QC

todos os Identity pacotes de NuGet dependentes são incluídos na estrutura compartilhada ASP.NET Core.

O pacote principal para o Identity é Microsoft. AspNetCore Identity .. Esse pacote contém o conjunto principal de interfaces para o ASP.NET Core Identity e é incluído pelo Microsoft.AspNetCore.Identity.EntityFrameworkCore .

Migrando para o ASP.NET Core Identity

Para obter mais informações e diretrizes sobre como migrar seu Identity repositório existente, consulte Identity migrar autenticação e .

Definindo a força da senha

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

AddDefault Identity e AddIdentity

AddDefaultIdentityfoi introduzido na ASP.NET Core 2.1. Chamar AddDefaultIdentity é semelhante a chamar o seguinte:

Consulte AddDefault Identity source para obter mais informações.

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

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

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

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

Próximas etapas

De Rick Anderson

ASP.NET Core Identity:

  • É uma API que dá suporte à funcionalidade de logon da interface do usuário.
  • Gerencia usuários, senhas, dados de perfil, funções, declarações, tokens, confirmação de email e muito mais.

Os usuários podem criar uma conta com as informações de logon armazenadas Identity no ou podem usar um provedor de logon externo. Os provedores de logon externos com suporte incluem Facebook, Google, Conta da Microsoft e 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. Scaffold Identity e exibir os arquivos gerados para revisar a interação do modelo com Identity .

Identitynormalmente é configurado usando um banco de dados SQL Server para armazenar nomes de usuário, senhas e dados de perfil. Como alternativa, outro armazenamento persistente pode ser usado, por exemplo, o Azure Table Armazenamento.

Neste tópico, você aprenderá a usar para registrar, fazer Identity logoff e fazer logoff de um usuário. Observação: os modelos tratam o nome de usuário e o email como o mesmo para os usuários. Para obter instruções mais detalhadas sobre como criar aplicativos que usam Identity o , consulte Próximas etapas.

plataforma de identidade da Microsoft é:

  • Uma evolução da plataforma Azure Active Directory desenvolvedor do Azure AD (Azure).
  • Não relacionado a ASP.NET Core Identity .

ASP.NET Core Identity adiciona a funcionalidade de logon da interface do usuário aos ASP.NET Web Core. Para proteger APIs Web e SPAs, use um dos seguintes:

IdentityServer4 é uma estrutura OpenID Connect e OAuth 2.0 para ASP.NET Core. IdentityO Server4 habilita os seguintes recursos de segurança:

  • Autenticação como serviço (AaaS)
  • SSO (single sign-on/off) em vários tipos de aplicativos
  • Controle de acesso para APIs
  • Gateway de Federação

Para obter mais informações, consulte Bem-vindo ao Identity Server4.

Exibir ou baixar o código de exemplo ( comobaixar).

Criar um aplicativo Web com autenticação

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

  • Selecione Arquivo > Novo > Project.
  • Selecione Aplicativo Web ASP.NET Core. Nomeia o projeto WebApp1 para ter o mesmo namespace que o download do projeto. Clique em OK.
  • Selecione um ASP.NET Core Web 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 Identity Razor Biblioteca de Classes expõe pontos de extremidade com a Identity área . 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 PMC (Console Gerenciador de Pacotes):

PM> Update-Database

Registrar e fazer logon de teste

Execute o aplicativo e registre um usuário. Dependendo do tamanho da tela, talvez seja necessário selecionar o botão de alternância de navegação para ver os links Registrar e Fazer logon.

Exibir o banco de Identity 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 mouse em dbo. Dados de exibição do AspNetUsers > :

Menu contextual na tabela AspNetUsers no Pesquisador de Objetos do SQL Server

Configurar Identity serviços

Os serviços são adicionados no 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 realçado anterior configura com Identity 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 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 anterior configura com Identity 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 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 pelo modelo não usa autorização. app.UseAuthorization está incluído para garantir que ele seja adicionado na ordem correta caso o aplicativo adicione autorização. UseRouting, UseAuthentication UseAuthorization , e devem ser chamados na ordem UseEndpoints mostrada no código anterior.

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

Scaffold Register, Login, LogOut e RegisterConfirmation

Adicione os Register arquivos , , e Login LogOut RegisterConfirmation . Siga a identidade do Scaffold em um Razor projeto com instruções de autorização para gerar o código mostrado nesta seção.

Examinar Registrar

Quando um usuário clica no botão Registrar na página, a ação Register é RegisterModel.OnPostAsync invocada. O usuário é criado por CreateAsync 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();
}

Desabilitar verificação de conta padrão

Com os modelos padrão, o usuário é redirecionado para o Account.RegisterConfirmation onde ele pode selecionar um link para que a conta seja confirmada. O padrão Account.RegisterConfirmation é usado somente 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 Logon é exibido quando:

  • O link Fazer logoff está selecionado.
  • Um usuário tenta acessar uma página restrita que não está autorizada a acessar ou quando não foi autenticado pelo sistema.

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

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 .

Faça logoff

O link Fazer logoff 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 precisa ser um redirecionamento para que o navegador execute uma nova solicitação e a identidade do return RedirectToPage(); usuário seja atualizada.

SignOutAsync limpa as declarações do usuário armazenadas em um cookie .

Post é 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 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 você estiver dentro, saia. Execute o aplicativo e selecione o Privacy link. Você é redirecionado à página de logon.

Apresenta Identity

Para explorar Identity mais detalhadamente:

Identity QC

todos os Identity pacotes de NuGet dependentes são incluídos na estrutura compartilhada ASP.NET Core.

O pacote principal para o Identity é Microsoft. AspNetCore Identity .. Esse pacote contém o conjunto principal de interfaces para o ASP.NET Core Identity e é incluído pelo Microsoft.AspNetCore.Identity.EntityFrameworkCore .

Migrando para o ASP.NET Core Identity

Para obter mais informações e diretrizes sobre como migrar seu Identity repositório existente, consulte Identity migrar autenticação e .

Definindo a força da senha

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

ADDDEFAULT Identity e AddIdentity

AddDefaultIdentityfoi introduzido no ASP.NET Core 2,1. Chamar AddDefaultIdentity é semelhante a chamar o seguinte:

Consulte a Identity fonte padrão para obter mais informações.

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

Para evitar a publicação de ativos estáticos Identity (folhas de estilo e arquivos JavaScript para Identity a 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