Confirmação de conta e de recuperação de senha no ASP.NET Core

Por Rick Anderson, Ponante Joe Audette

Este tutorial mostra como criar um aplicativo de ASP.NET Core com confirmação de email e redefinição de senha. Este tutorial não é um tópico inicial. Você deve estar familiarizado com:

Pré-requisitos

SDK do .NET Core 3.0 ou posterior

Criar e testar um aplicativo Web com autenticação

Execute os comandos a seguir para criar um aplicativo Web com autenticação.

dotnet new webapp -au Individual -uld -o WebPWrecover
cd WebPWrecover
dotnet run

Execute o aplicativo, selecione o link Registrar e registre um usuário. Depois de registrado, você será redirecionado para a página que contém /Identity/Account/RegisterConfirmation um link para simular a confirmação de email:

  • Selecione o link Click here to confirm your account.
  • Selecione o link Logon e entre com as mesmas credenciais.
  • Selecione o Hello YourEmail@provider.com! link, que redireciona você para a /Identity/Account/Manage/PersonalData página.
  • Selecione a guia Dados pessoais à esquerda e, em seguida, selecione Excluir.

Configurar um provedor de email

Neste tutorial, o SendGrid é usado para enviar email. Você precisa de uma conta e uma chave do SendGrid para enviar email. Você pode usar outros provedores de email. Recomendamos que você use o SendGrid ou outro serviço de email para enviar email. O SMTP é difícil de proteger e configurar corretamente.

A conta do SendGrid pode exigir a adição de um Remetente.

Crie uma classe para buscar a chave de email segura. Para este exemplo, crie Services/AuthMessageSenderOptions.cs:

public class AuthMessageSenderOptions
{
    public string SendGridKey { get; set; }
}

Configurar segredos do usuário do SendGrid

De definir SendGridKey o com a ferramenta secret-manager. Por exemplo:

dotnet user-secrets set SendGridKey <key>

Successfully saved SendGridKey to the secret store.

No Windows, o Gerenciador de Segredos armazena pares de chaves/valores em umsecrets.jsno arquivo no diretório %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId> .

O conteúdo da secrets.jsno arquivo não é criptografado. A marcação a seguir mostra asecrets.jsno arquivo. O SendGridKey valor foi removido.

{
  "SendGridKey": "<key removed>"
}

Para obter mais informações, consulte o Padrão de opções e configuração.

Instalar o SendGrid

Este tutorial mostra como adicionar notificações por email por meio do SendGrid,mas você pode enviar email usando SMTP e outros mecanismos.

Instale o SendGrid NuGet pacote:

No console Gerenciador de Pacotes, insira o seguinte comando:

Install-Package SendGrid

Consulte Introdução com o SendGrid gratuitamente para se registrar para uma conta gratuita do SendGrid.

Implementar IEmailSender

Para implementar IEmailSender o , crie Services/EmailSender.cs com um código semelhante ao seguinte:

using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
using System.Threading.Tasks;

namespace WebPWrecover.Services
{
    public class EmailSender : IEmailSender
    {
        public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor)
        {
            Options = optionsAccessor.Value;
        }

        public AuthMessageSenderOptions Options { get; } //set only via Secret Manager

        public Task SendEmailAsync(string email, string subject, string message)
        {
            return Execute(Options.SendGridKey, subject, message, email);
        }

        public Task Execute(string apiKey, string subject, string message, string email)
        {
            var client = new SendGridClient(apiKey);
            var msg = new SendGridMessage()
            {
                From = new EmailAddress("Joe@contoso.com", "Password Recovery"),
                Subject = subject,
                PlainTextContent = message,
                HtmlContent = message
            };
            msg.AddTo(new EmailAddress(email));

            // Disable click tracking.
            // See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
            msg.SetClickTracking(false, false);

            return client.SendEmailAsync(msg);
        }
    }
}

Configurar a inicialização para dar suporte ao email

Adicione o seguinte código ao ConfigureServices método no arquivo Startup.cs:

  • Adicione EmailSender como um serviço transitório.
  • Registre a instância AuthMessageSenderOptions de configuração.
public void ConfigureServices(IServiceCollection services)
{

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>(
                  options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    // requires
    // using Microsoft.AspNetCore.Identity.UI.Services;
    // using WebPWrecover.Services;
    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);

    services.AddRazorPages();
}

Scaffold RegisterConfirmation

Siga as instruções para Scaffold Identity e scaffold RegisterConfirmation .

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

Registrar, confirmar email e redefinir senha

Execute o aplicativo Web e teste o fluxo de recuperação de senha e confirmação da conta.

  • Executar o aplicativo e registrar um novo usuário
  • Verifique seu email para o link de confirmação da conta. Confira Depurar email se você não receber o email.
  • Clique no link para confirmar seu email.
  • Entre com seu email e senha.
  • Saia.

Testar a redefinição de senha

  • Se você estiver dentro, selecione Logout.
  • Selecione o link Fazer logoff e selecione o link Esqueceu sua senha?.
  • Insira o email usado para registrar a conta.
  • Um email com um link para redefinir sua senha é enviado. Verifique seu email e clique no link para redefinir sua senha. Depois que a senha for redefinida com êxito, você poderá entrar com seu email e a nova senha.

Resend email confirmation

No ASP.NET Core 5.0 e posterior, selecione o link Resend email confirmation link na página Logon.

Alterar o tempo de atividade e email

O tempo de inatividade padrão é de 14 dias. O código a seguir define o tempo de inatividade como 5 dias:

services.ConfigureApplicationCookie(o => {
    o.ExpireTimeSpan = TimeSpan.FromDays(5);
    o.SlidingExpiration = true;
});

Alterar todos os tempos de vida do token de proteção de dados

O código a seguir altera o período de tempo de tempo de todos os tokens de proteção de dados para 3 horas:

public void ConfigureServices(IServiceCollection services)
{

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>(
                  options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.Configure<DataProtectionTokenProviderOptions>(o =>
       o.TokenLifespan = TimeSpan.FromHours(3));

    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);

    services.AddRazorPages();
}

Os tokens de usuário Identity integrados (consulte AspNetCore/src/ Identity /Extensions.Core/src/TokenOptions.cs ) têm um tempo máximo de um dia.

Alterar o tempo de vida do token de email

O tempo de vida do token padrão dos Identity tokens de usuário é um dia. Esta seção mostra como alterar o tempo de vida do token de email.

Adicione um DataProtectorTokenProvider <TUser> personalizado e DataProtectionTokenProviderOptions :

public class CustomEmailConfirmationTokenProvider<TUser>
                                       : DataProtectorTokenProvider<TUser> where TUser : class
{
    public CustomEmailConfirmationTokenProvider(IDataProtectionProvider dataProtectionProvider,
        IOptions<EmailConfirmationTokenProviderOptions> options,
        ILogger<DataProtectorTokenProvider<TUser>> logger)
                                          : base(dataProtectionProvider, options, logger)
    {

    }
}
public class EmailConfirmationTokenProviderOptions : DataProtectionTokenProviderOptions
{
    public EmailConfirmationTokenProviderOptions()
    {
        Name = "EmailDataProtectorTokenProvider";
        TokenLifespan = TimeSpan.FromHours(4);
    }
}

Adicione o provedor personalizado ao contêiner de serviço:

public void ConfigureServices(IServiceCollection services)
{

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>(config =>
    {
        config.SignIn.RequireConfirmedEmail = true;
        config.Tokens.ProviderMap.Add("CustomEmailConfirmation",
            new TokenProviderDescriptor(
                typeof(CustomEmailConfirmationTokenProvider<IdentityUser>)));
        config.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmation";
      }).AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddTransient<CustomEmailConfirmationTokenProvider<IdentityUser>>();

    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);

    services.AddRazorPages();
}

Depurar email

Se você não conseguir fazer o email funcionar:

  • De configurar um ponto de EmailSender.Execute interrupção em para verificar SendGridClient.SendEmailAsync se é chamado.
  • Crie um aplicativo de console para enviar email usando código semelhante ao EmailSender.Execute .
  • Revise a página Atividade de Email.
  • Verifique sua pasta de spam.
  • Experimente outro alias de email em um provedor de email diferente (Microsoft, Yahoo, Gmail etc.)
  • Tente enviar para diferentes contas de email.

Uma melhor prática de segurança é não usar segredos de produção em teste e desenvolvimento. Se você publicar o aplicativo no Azure, de definir os segredos do SendGrid como configurações de aplicativo no portal do Aplicativo Web do Azure. O sistema de configuração é definido para ler chaves de variáveis de ambiente.

Combinar contas de logon local e social

Para concluir esta seção, primeiro você deve habilitar um provedor de autenticação externo. Confira Facebook, Google e autenticação de provedor externo.

Você pode combinar contas locais e sociais clicando no link de email. Na sequência a seguir, " " é criado primeiro como um logon local; no entanto, você pode criar a conta como um logon social primeiro e, em RickAndMSFT@gmail.com seguida, adicionar um logon local.

Aplicativo Web: RickAndMSFT@gmail.com autenticado pelo usuário

Clique no link Gerenciar. Observe os 0 externos (logons sociais) associados a essa conta.

Gerenciar exibição

Clique no link para outro serviço de logon e aceite as solicitações do aplicativo. Na imagem a seguir, o Facebook é o provedor de autenticação externo:

Gerenciar a exibição de logons externos listando o Facebook

As duas contas foram combinadas. Você pode entrar com qualquer uma das contas. Talvez você queira que os usuários adicionem contas locais no caso de o serviço de autenticação de logon social estar inocentado ou, mais provavelmente, eles tenham perdido o acesso à conta social.

Habilitar a confirmação da conta depois que um site tiver usuários

A habilitação da confirmação da conta em um site com usuários bloqueia todos os usuários existentes. Os usuários existentes são bloqueados porque suas contas não são confirmadas. Para resolver o bloqueio de usuário existente, use uma das seguintes abordagens:

  • Atualize o banco de dados para marcar todos os usuários existentes como sendo confirmados.
  • Confirme os usuários existentes. Por exemplo, emails de envio em lote com links de confirmação.

Pré-requisitos

SDK do .NET Core 2.2 ou posterior

Criar um aplicativo Web e um scaffold Identity

Execute os comandos a seguir para criar um aplicativo Web com autenticação.

dotnet new webapp -au Individual -uld -o WebPWrecover
cd WebPWrecover
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet tool install -g dotnet-aspnet-codegenerator
dotnet aspnet-codegenerator identity -dc WebPWrecover.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.Logout;Account.ConfirmEmail"
dotnet ef database drop -f
dotnet ef database update
dotnet run

Observação

Se estiver configurado no , a configuração de atributo poderá ser necessária PasswordOptions para a propriedade em páginas com Startup.ConfigureServices [StringLength] Password Identity scaffolding. Uma InputModel Password propriedade é encontrada no arquivo após Areas/Identity/Pages/Account/Register.cshtml.cs o scaffolding Identity .

Testar o novo registro de usuário

Execute o aplicativo, selecione o link Registrar e registre um usuário. Neste ponto, a única validação no email é com o [EmailAddress] atributo . Depois de enviar o registro, você será conectado ao aplicativo. Posteriormente no tutorial, o código é atualizado para que novos usuários não possam entrar até que seu email seja validado.

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

Observe que o campo da EmailConfirmed tabela é False .

Talvez você queira usar esse email novamente na próxima etapa quando o aplicativo enviar um email de confirmação. Clique com o botão direito do mouse na linha e selecione Excluir. A exclusão do alias de email facilita as etapas a seguir.

Exigir confirmação por email

É uma melhor prática confirmar o email de um novo registro de usuário. A confirmação de email ajuda a verificar se ela não está representando outra pessoa (ou seja, ela não se registrou com o email de outra pessoa). Suponha que você tenha um fórum de discussão e quisesse impedir yli@example.com que " " se registra como " nolivetto@contoso.com ". Sem confirmação de email, nolivetto@contoso.com " " poderia receber emails indesejados do seu aplicativo. Suponha que o usuário se registrou acidentalmente como " ylo@example.com " e não observou o erro de ortagem de "yli". Eles não seriam capazes de usar a recuperação de senha porque o aplicativo não tem seu email correto. A confirmação por email fornece proteção limitada contra bots. A confirmação de email não fornece proteção contra usuários mal-intencionados com muitas contas de email.

Geralmente, você deseja impedir que novos usuários postem dados em seu site antes que eles tenham um email confirmado.

Atualize Startup.ConfigureServices para exigir um email confirmado:

public void ConfigureServices(IServiceCollection services)
{

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>(config =>
    {
        config.SignIn.RequireConfirmedEmail = true;
    })
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    // requires
    // using Microsoft.AspNetCore.Identity.UI.Services;
    // using WebPWrecover.Services;
    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

config.SignIn.RequireConfirmedEmail = true; impede que os usuários registrados se registrarem até que seu email seja confirmado.

Configurar provedor de email

Neste tutorial, o SendGrid é usado para enviar email. Você precisa de uma conta e uma chave do SendGrid para enviar email. Você pode usar outros provedores de email. ASP.NET Core 2.x inclui System.Net.Mail , que permite que você envie email de seu aplicativo. Recomendamos que você use o SendGrid ou outro serviço de email para enviar email. O SMTP é difícil de proteger e configurar corretamente.

Crie uma classe para buscar a chave de email segura. Para este exemplo, crie Services/AuthMessageSenderOptions.cs:

public class AuthMessageSenderOptions
{
    public string SendGridUser { get; set; }
    public string SendGridKey { get; set; }
}

Configurar segredos do usuário do SendGrid

De definir SendGridUser o e com a ferramenta SendGridKey secret-manager. Por exemplo:

C:/WebAppl>dotnet user-secrets set SendGridUser RickAndMSFT
info: Successfully saved SendGridUser = RickAndMSFT to the secret store.

No Windows, o Gerenciador de Segredos armazena pares de chaves/valores em umsecrets.jsno arquivo no diretório %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId> .

O conteúdo da secrets.jsno arquivo não é criptografado. A marcação a seguir mostra osecrets.jsno arquivo . O SendGridKey valor foi removido.

{
  "SendGridUser": "RickAndMSFT",
  "SendGridKey": "<key removed>"
}

Para obter mais informações, consulte o Padrão de opções e configuração.

Instalar o SendGrid

Este tutorial mostra como adicionar notificações por email por meio do SendGrid,mas você pode enviar email usando SMTP e outros mecanismos.

Instale o SendGrid NuGet pacote:

No console Gerenciador de Pacotes, insira o seguinte comando:

Install-Package SendGrid

Consulte Introdução com o SendGrid gratuitamente para se registrar para uma conta gratuita do SendGrid.

Implementar IEmailSender

Para implementar IEmailSender o , crie Services/EmailSender.cs com um código semelhante ao seguinte:

using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
using System.Threading.Tasks;

namespace WebPWrecover.Services
{
    public class EmailSender : IEmailSender
    {
        public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor)
        {
            Options = optionsAccessor.Value;
        }

        public AuthMessageSenderOptions Options { get; } //set only via Secret Manager

        public Task SendEmailAsync(string email, string subject, string message)
        {
            return Execute(Options.SendGridKey, subject, message, email);
        }

        public Task Execute(string apiKey, string subject, string message, string email)
        {
            var client = new SendGridClient(apiKey);
            var msg = new SendGridMessage()
            {
                From = new EmailAddress("Joe@contoso.com", "Joe Smith"),
                Subject = subject,
                PlainTextContent = message,
                HtmlContent = message
            };
            msg.AddTo(new EmailAddress(email));

            // Disable click tracking.
            // See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
            msg.SetClickTracking(false, false);

            return client.SendEmailAsync(msg);
        }
    }
}

Configurar a inicialização para dar suporte ao email

Adicione o seguinte código ao ConfigureServices método no arquivo Startup.cs:

  • Adicione EmailSender como um serviço transitório.
  • Registre a instância AuthMessageSenderOptions de configuração.
public void ConfigureServices(IServiceCollection services)
{

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>(config =>
    {
        config.SignIn.RequireConfirmedEmail = true;
    })
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    // requires
    // using Microsoft.AspNetCore.Identity.UI.Services;
    // using WebPWrecover.Services;
    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Habilitar a confirmação da conta e a recuperação de senha

O modelo tem o código para confirmação de conta e recuperação de senha. Encontre o OnPostAsync método em Areas/ Identity /Pages/Account/Register.cshtml.cs.

Impeça que usuários recém-registrados se inscrevam automaticamente comentando a seguinte linha:

await _signInManager.SignInAsync(user, isPersistent: false);

O método completo é mostrado com a linha alterada realçada:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    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);
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { 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>.");

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

Registrar, confirmar email e redefinir senha

Execute o aplicativo Web e teste o fluxo de recuperação de senha e confirmação da conta.

  • Executar o aplicativo e registrar um novo usuário
  • Verifique seu email para o link de confirmação da conta. Confira Depurar email se você não receber o email.
  • Clique no link para confirmar seu email.
  • Entre com seu email e senha.
  • Saia.

Exibir a página gerenciar

Selecione o nome de usuário no navegador: janela  do navegador com nome de usuário

A página gerenciar é exibida com a guia Perfil selecionada. O Email mostra uma caixa de seleção indicando que o email foi confirmado.

Testar a redefinição de senha

  • Se você estiver dentro, selecione Logout.
  • Selecione o link Fazer logoff e selecione o link Esqueceu sua senha?.
  • Insira o email usado para registrar a conta.
  • Um email com um link para redefinir sua senha é enviado. Verifique seu email e clique no link para redefinir sua senha. Depois que a senha for redefinida com êxito, você poderá entrar com seu email e a nova senha.

Alterar o tempo de atividade e email

O tempo de inatividade padrão é de 14 dias. O código a seguir define o tempo de inatividade como 5 dias:

services.ConfigureApplicationCookie(o => {
    o.ExpireTimeSpan = TimeSpan.FromDays(5);
    o.SlidingExpiration = true;
});

Alterar todos os tempos de vida do token de proteção de dados

O código a seguir altera todos os tokens de proteção de dados período de tempo limite para 3 horas:

public void ConfigureServices(IServiceCollection services)
{

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>(config =>
    {
        config.SignIn.RequireConfirmedEmail = true;
    })
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.Configure<DataProtectionTokenProviderOptions>(o =>
                o.TokenLifespan = TimeSpan.FromHours(3));

    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Os Identity tokens de usuário internos (consulte AspNetCore/src/ Identity /Extensions.Core/src/TokenOptions.cs ) têm um tempo limite de um dia.

Alterar o ciclo de vida do token de email

A vida útil do token padrão dos Identity tokens de usuário é de um dia. Esta seção mostra como alterar o ciclo de vida do token de email.

Adicione um DataProtectorTokenProvider <TUser> personalizado e DataProtectionTokenProviderOptions :

public class CustomEmailConfirmationTokenProvider<TUser> 
                                       : DataProtectorTokenProvider<TUser> where TUser : class
{
    public CustomEmailConfirmationTokenProvider(IDataProtectionProvider dataProtectionProvider,
        IOptions<EmailConfirmationTokenProviderOptions> options) 
                                                        : base(dataProtectionProvider, options)
    {

    }
}
public class EmailConfirmationTokenProviderOptions : DataProtectionTokenProviderOptions
{
    public EmailConfirmationTokenProviderOptions()
    {
        Name = "EmailDataProtectorTokenProvider";
        TokenLifespan = TimeSpan.FromHours(4);
    }
}

Adicione o provedor personalizado ao contêiner de serviço:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>(config =>
    {
        config.SignIn.RequireConfirmedEmail = true;
        config.Tokens.ProviderMap.Add("CustomEmailConfirmation",
            new TokenProviderDescriptor(
                typeof(CustomEmailConfirmationTokenProvider<IdentityUser>)));
        config.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmation";                
    })
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddTransient<CustomEmailConfirmationTokenProvider<IdentityUser>>();
    services.AddTransient<IEmailSender, EmailSender>();            
    services.Configure<AuthMessageSenderOptions>(Configuration); // For SendGrid key.

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Reenviar confirmação de email

Consulte este problema do GitHub.

Depurar email

Se você não puder obter emails funcionando:

  • Defina um ponto de interrupção em EmailSender.Execute para verificar SendGridClient.SendEmailAsync é chamado.
  • Crie um aplicativo de console para enviar emails usando código semelhante para EmailSender.Execute .
  • Examine a página atividade de email .
  • Verifique sua pasta de spam.
  • Experimente outro alias de email em um provedor de email diferente (Microsoft, Yahoo, Gmail, etc.)
  • Tente enviar para contas de email diferentes.

Uma prática recomendada de segurança é não usar segredos de produção em teste e desenvolvimento. Se você publicar o aplicativo no Azure, poderá definir os segredos do SendGrid como configurações do aplicativo no portal do aplicativo Web do Azure. O sistema de configuração é configurado para ler chaves de variáveis de ambiente.

Combinar contas de logon sociais e locais

Para concluir esta seção, primeiro você deve habilitar um provedor de autenticação externa. Consulte Facebook, Google e autenticação de provedor externo.

Você pode combinar contas locais e sociais clicando no link de email. Na sequência a seguir, " RickAndMSFT@gmail.com " é criado primeiro como um logon local; no entanto, você pode criar a conta como um logon social primeiro e, em seguida, adicionar um logon local.

Aplicativo Web: RickAndMSFT@gmail.com usuário autenticado

Clique no link gerenciar . Observe o 0 externo (logons sociais) associado a essa conta.

Gerenciar modo de exibição

Clique no link para outro serviço de logon e aceite as solicitações do aplicativo. Na imagem a seguir, o Facebook é o provedor de autenticação externa:

Gerenciar seus logons externos exibir listando o Facebook

As duas contas foram combinadas. Você pode entrar com qualquer uma das contas. Talvez você queira que os usuários adicionem contas locais caso o serviço de autenticação de logon social esteja inativo ou, provavelmente, tenha perdido o acesso à sua conta social.

Habilitar confirmação de conta depois que um site tiver usuários

Habilitar a confirmação de conta em um site com usuários bloqueia todos os usuários existentes. Os usuários existentes são bloqueados porque suas contas não são confirmadas. Para contornar o bloqueio de usuário existente, use uma das seguintes abordagens:

  • Atualize o banco de dados para marcar todos os usuários existentes como sendo confirmados.
  • Confirme os usuários existentes. Por exemplo, enviar emails por lote com links de confirmação.