Account confirmation and password recovery in ASP.NET Core (Conferma dell'account e recupero della password in ASP.NET Core)
Di Rick Anderson, Ponant e Joe Audette
Questa esercitazione illustra come creare un'app ASP.NET Core con la conferma tramite posta elettronica e la reimpostazione della password. Questa esercitazione non è un argomento iniziale. È necessario avere familiarità con:
Per Blazor indicazioni su come aggiungere o sostituire le linee guida contenute in questo articolo, vedere le risorse seguenti:
Prerequisiti
- .NET Core 6.0 SDK o versione successiva
- Inviare correttamente un messaggio di posta elettronica da un'app console C#.
Creare e testare un'app Web con l'autenticazione
Eseguire i comandi seguenti per creare un'app Web con autenticazione.
dotnet new webapp -au Individual -o WebPWrecover
cd WebPWrecover
dotnet run
Registrare l'utente con conferma tramite posta elettronica simulata
Eseguire l'app, selezionare il collegamento Registra e registrare un utente. Dopo la registrazione, si viene reindirizzati alla pagina a /Identity/Account/RegisterConfirmation
che contiene un collegamento per simulare la conferma tramite posta elettronica:
- Selezionare il collegamento
Click here to confirm your account
. - Selezionare il collegamento Account di accesso e accedere con le stesse credenziali.
- Selezionare il
Hello YourEmail@provider.com!
collegamento che reindirizza alla/Identity/Account/Manage/PersonalData
pagina. - Selezionare la scheda Dati personali a sinistra e quindi selezionare Elimina.
Il Click here to confirm your account
collegamento viene visualizzato perché un IEmailSender non è stato implementato e registrato con il contenitore di inserimento delle dipendenze. Vedere l'origineRegisterConfirmation
.
Nota
I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).
Configurare un provider di posta elettronica
In questa esercitazione SendGrid viene usato per inviare messaggi di posta elettronica. Per inviare un messaggio di posta elettronica, è necessario un account SendGrid e una chiave. È consigliabile usare SendGrid o un altro servizio di posta elettronica per inviare messaggi di posta elettronica anziché SMTP. SMTP è difficile da proteggere e configurare correttamente.
L'account SendGrid potrebbe richiedere l'aggiunta di un mittente.
Creare una classe per recuperare la chiave di posta elettronica sicura. Per questo esempio, creare Services/AuthMessageSenderOptions.cs
:
namespace WebPWrecover.Services;
public class AuthMessageSenderOptions
{
public string? SendGridKey { get; set; }
}
Configurare i segreti utente di SendGrid
SendGridKey
Impostare con lo strumento secret-manager. Ad esempio:
dotnet user-secrets set SendGridKey <key>
Successfully saved SendGridKey to the secret store.
In Windows Secret Manager archivia coppie chiave/valore in un secrets.json
file nella %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId>
directory.
Il contenuto del secrets.json
file non è crittografato. Il markup seguente illustra il secrets.json
file. Il SendGridKey
valore è stato rimosso.
{
"SendGridKey": "<key removed>"
}
Per altre informazioni, vedere Modello e configurazione delle opzioni.
Installare SendGrid
Questa esercitazione illustra come aggiungere notifiche di posta elettronica tramite SendGrid, ma è possibile usare altri provider di posta elettronica.
Installare il SendGrid
pacchetto NuGet:
Nella console di Gestione pacchetti immettere il comando seguente:
Install-Package SendGrid
Vedere Introduzione a SendGrid gratuitamente per registrarsi per un account SendGrid gratuito.
Implementare IEmailSender
Per implementare IEmailSender
, creare Services/EmailSender.cs
con codice simile al seguente:
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
namespace WebPWrecover.Services;
public class EmailSender : IEmailSender
{
private readonly ILogger _logger;
public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor,
ILogger<EmailSender> logger)
{
Options = optionsAccessor.Value;
_logger = logger;
}
public AuthMessageSenderOptions Options { get; } //Set with Secret Manager.
public async Task SendEmailAsync(string toEmail, string subject, string message)
{
if (string.IsNullOrEmpty(Options.SendGridKey))
{
throw new Exception("Null SendGridKey");
}
await Execute(Options.SendGridKey, subject, message, toEmail);
}
public async Task Execute(string apiKey, string subject, string message, string toEmail)
{
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(toEmail));
// Disable click tracking.
// See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
msg.SetClickTracking(false, false);
var response = await client.SendEmailAsync(msg);
_logger.LogInformation(response.IsSuccessStatusCode
? $"Email to {toEmail} queued successfully!"
: $"Failure Email to {toEmail}");
}
}
Configurare l'app per supportare la posta elettronica
Aggiungere il codice seguente al file Program.cs
:
- Aggiungere
EmailSender
come servizio temporaneo. - Registrare l'istanza di
AuthMessageSenderOptions
configurazione.
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
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();
Disabilitare la verifica dell'account predefinita quando è stato eseguito lo scaffolding di Account.RegisterConfirmation
Questa sezione si applica solo quando Account.RegisterConfirmation
viene eseguito lo scaffolding. Ignorare questa sezione se non è stato sottoposto a scaffolding Account.RegisterConfirmation
.
L'utente viene reindirizzato alla Account.RegisterConfirmation
posizione in cui è possibile selezionare un collegamento per confermare l'account. Il valore predefinito viene usato solo per i test, la verifica automatica dell'account deve essere disabilitata Account.RegisterConfirmation
in un'app di produzione.
Per richiedere un account confermato e impedire l'accesso immediato durante la registrazione, impostare DisplayConfirmAccountLink = false
nel file con scaffolding /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
namespace WebPWrecover.Areas.Identity.Pages.Account
{
[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;
}
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public string Email { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public bool DisplayConfirmAccountLink { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public string EmailConfirmationUrl { get; set; }
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
{
if (email == null)
{
return RedirectToPage("/Index");
}
returnUrl = returnUrl ?? Url.Content("~/");
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();
}
}
}
Questo passaggio è necessario solo quando Account.RegisterConfirmation
viene eseguito lo scaffolding. RegisterConfirmation non sottoposto a scaffolding rileva automaticamente quando un IEmailSender è stato implementato e registrato con il contenitore di inserimento delle dipendenze.
Registrare, confermare la posta elettronica e reimpostare la password
Eseguire l'app Web e testare il flusso di conferma e ripristino delle password dell'account.
- Eseguire l'app e registrare un nuovo utente
- Controllare l'indirizzo di posta elettronica per il collegamento di conferma dell'account. Vedere Eseguire il debug del messaggio di posta elettronica se non si riceve il messaggio di posta elettronica.
- Fare clic sul collegamento per confermare il messaggio di posta elettronica.
- Accedere con l'indirizzo di posta elettronica e la password.
- Disconnettersi.
Testare la reimpostazione della password
- Se è stato eseguito l'accesso, selezionare Disconnetti.
- Selezionare il collegamento Accedi e selezionare il collegamento Password dimenticata?
- Immettere il messaggio di posta elettronica usato per registrare l'account.
- Viene inviato un messaggio di posta elettronica con un collegamento per reimpostare la password. Controllare il messaggio di posta elettronica e fare clic sul collegamento per reimpostare la password. Dopo la reimpostazione della password, è possibile accedere con il messaggio di posta elettronica e la nuova password.
Inviare di nuovo la conferma tramite posta elettronica
Selezionare il collegamento Invia di nuovo conferma tramite posta elettronica nella pagina Di accesso .
Modificare il timeout dell'attività e della posta elettronica
Il timeout di inattività predefinito è 14 giorni. Il codice seguente imposta il timeout di inattività su 5 giorni:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
builder.Services.ConfigureApplicationCookie(o => {
o.ExpireTimeSpan = TimeSpan.FromDays(5);
o.SlidingExpiration = true;
});
var app = builder.Build();
// Code removed for brevity
Modificare tutta la durata dei token di protezione dei dati
Il codice seguente modifica il periodo di timeout di tutti i token di protezione dei dati a 3 ore:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
builder.Services.Configure<DataProtectionTokenProviderOptions>(o =>
o.TokenLifespan = TimeSpan.FromHours(3));
var app = builder.Build();
// Code removed for brevity.
I token utente predefiniti Identity (vedere AspNetCore/src//IdentityExtensions.Core/src/TokenOptions.cs )hanno un timeout di un giorno.
Modificare la durata del token di posta elettronica
La durata del token predefinita dei token utente è un giorno. Identity Questa sezione illustra come modificare la durata del token di posta elettronica.
Aggiungere un oggetto personalizzato DataProtectorTokenProvider<TUser> 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);
}
}
Aggiungere il provider personalizzato al contenitore del servizio:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
using WebPWrecover.TokenProviders;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(config =>
{
config.SignIn.RequireConfirmedEmail = true;
config.Tokens.ProviderMap.Add("CustomEmailConfirmation",
new TokenProviderDescriptor(
typeof(CustomEmailConfirmationTokenProvider<IdentityUser>)));
config.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmation";
}).AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddTransient<CustomEmailConfirmationTokenProvider<IdentityUser>>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
var app = builder.Build();
// Code removed for brevity.
Eseguire il debug della posta elettronica
Se non è possibile ricevere messaggi di posta elettronica funzionanti:
- Impostare un punto di interruzione in
EmailSender.Execute
per verificareSendGridClient.SendEmailAsync
che venga chiamato . - Creare un'app console per inviare messaggi di posta elettronica usando codice simile a
EmailSender.Execute
. - Esaminare la pagina Attività di posta elettronica.
- Controllare la cartella della posta indesiderata.
- Provare un altro alias di posta elettronica su un provider di posta elettronica diverso (Microsoft, Yahoo, Gmail e così via)
- Provare a inviare a account di posta elettronica diversi.
Una procedura consigliata per la sicurezza consiste nel non usare segreti di produzione in fase di test e sviluppo. Se si pubblica l'app in Azure, impostare i segreti SendGrid come impostazioni dell'applicazione nel portale di App Web di Azure. Il sistema di configurazione è configurato per leggere le chiavi dalle variabili di ambiente.
Combinare account di accesso di social network e locali
Per completare questa sezione, è prima necessario abilitare un provider di autenticazione esterno. Vedere Autenticazione del provider esterno, Google e Facebook.
È possibile combinare account locali e social facendo clic sul collegamento di posta elettronica. Nella sequenza seguente "RickAndMSFT@gmail.com" viene prima creato come account di accesso locale. Tuttavia, è possibile creare prima l'account come account di accesso di social networking e quindi aggiungere un account di accesso locale.
Fare clic sul collegamento Gestisci . Si notino i 0 account esterni (account di accesso di social networking) associati a questo account.
Fare clic sul collegamento a un altro servizio di accesso e accettare le richieste dell'app. Nell'immagine seguente Facebook è il provider di autenticazione esterno:
I due conti sono stati combinati. È possibile accedere con uno dei due account. È possibile che gli utenti aggiungano account locali nel caso in cui il servizio di autenticazione dell'account di accesso social sia inattivo o che abbiano perso l'accesso al proprio account di social networking.
Abilitare la conferma dell'account dopo che un sito ha utenti
L'abilitazione della conferma dell'account in un sito con gli utenti blocca tutti gli utenti esistenti. Gli utenti esistenti vengono bloccati perché gli account non vengono confermati. Per aggirare il blocco utente esistente, usare uno degli approcci seguenti:
- Aggiornare il database per contrassegnare tutti gli utenti esistenti come confermati.
- Confermare gli utenti esistenti. Ad esempio, inviare messaggi di posta elettronica in batch con collegamenti di conferma.
Prerequisiti
.NET Core 3.0 SDK o versione successiva
Creare e testare un'app Web con l'autenticazione
Eseguire i comandi seguenti per creare un'app Web con autenticazione.
dotnet new webapp -au Individual -uld -o WebPWrecover
cd WebPWrecover
dotnet run
Eseguire l'app, selezionare il collegamento Registra e registrare un utente. Dopo la registrazione, si viene reindirizzati alla pagina a /Identity/Account/RegisterConfirmation
che contiene un collegamento per simulare la conferma tramite posta elettronica:
- Selezionare il collegamento
Click here to confirm your account
. - Selezionare il collegamento Account di accesso e accedere con le stesse credenziali.
- Selezionare il
Hello YourEmail@provider.com!
collegamento, che reindirizza alla/Identity/Account/Manage/PersonalData
pagina. - Selezionare la scheda Dati personali a sinistra e quindi selezionare Elimina.
Configurare un provider di posta elettronica
In questa esercitazione SendGrid viene usato per inviare messaggi di posta elettronica. È possibile usare altri provider di posta elettronica. È consigliabile usare SendGrid o un altro servizio di posta elettronica per inviare messaggi di posta elettronica. SMTP è difficile da configurare in modo che la posta non sia contrassegnata come posta indesiderata.
L'account SendGrid potrebbe richiedere l'aggiunta di un mittente.
Creare una classe per recuperare la chiave di posta elettronica sicura. Per questo esempio, creare Services/AuthMessageSenderOptions.cs
:
namespace WebPWrecover.Services;
public class AuthMessageSenderOptions
{
public string? SendGridKey { get; set; }
}
Configurare i segreti utente di SendGrid
SendGridKey
Impostare con lo strumento secret-manager. Ad esempio:
dotnet user-secrets set SendGridKey <SG.key>
Successfully saved SendGridKey = SG.keyVal to the secret store.
In Windows Secret Manager archivia coppie chiave/valore in un secrets.json
file nella %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId>
directory.
Il contenuto del secrets.json
file non è crittografato. Il markup seguente illustra il secrets.json
file. Il SendGridKey
valore è stato rimosso.
{
"SendGridKey": "<key removed>"
}
Per altre informazioni, vedere Modello e configurazione delle opzioni.
Installare SendGrid
Questa esercitazione illustra come aggiungere notifiche di posta elettronica tramite SendGrid, ma è possibile inviare messaggi di posta elettronica usando SMTP e altri meccanismi.
Installare il SendGrid
pacchetto NuGet:
Nella console di Gestione pacchetti immettere il comando seguente:
Install-Package SendGrid
Vedere Introduzione a SendGrid gratuitamente per registrarsi per un account SendGrid gratuito.
Implementare IEmailSender
Per implementare IEmailSender
, creare Services/EmailSender.cs
con codice simile al seguente:
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
namespace WebPWrecover.Services;
public class EmailSender : IEmailSender
{
private readonly ILogger _logger;
public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor,
ILogger<EmailSender> logger)
{
Options = optionsAccessor.Value;
_logger = logger;
}
public AuthMessageSenderOptions Options { get; } //Set with Secret Manager.
public async Task SendEmailAsync(string toEmail, string subject, string message)
{
if (string.IsNullOrEmpty(Options.SendGridKey))
{
throw new Exception("Null SendGridKey");
}
await Execute(Options.SendGridKey, subject, message, toEmail);
}
public async Task Execute(string apiKey, string subject, string message, string toEmail)
{
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(toEmail));
// Disable click tracking.
// See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
msg.SetClickTracking(false, false);
var response = await client.SendEmailAsync(msg);
_logger.LogInformation(response.IsSuccessStatusCode
? $"Email to {toEmail} queued successfully!"
: $"Failure Email to {toEmail}");
}
}
Configurare l'avvio per supportare la posta elettronica
Aggiungere il codice seguente al ConfigureServices
metodo nel Startup.cs
file :
- Aggiungere
EmailSender
come servizio temporaneo. - Registrare l'istanza di
AuthMessageSenderOptions
configurazione.
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
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();
Scaffold RegisterConfirmation
Seguire le istruzioni per Scaffolding e scaffolding IdentityAccount\RegisterConfirmation
.
Disabilitare la verifica dell'account predefinita quando è stato eseguito lo scaffolding di Account.RegisterConfirmation
Questa sezione si applica solo quando Account.RegisterConfirmation
viene eseguito lo scaffolding. Ignorare questa sezione se non è stato sottoposto a scaffolding Account.RegisterConfirmation
.
L'utente viene reindirizzato alla Account.RegisterConfirmation
posizione in cui è possibile selezionare un collegamento per confermare l'account. Il valore predefinito viene usato solo per i test, la verifica automatica dell'account deve essere disabilitata Account.RegisterConfirmation
in un'app di produzione.
Per richiedere un account confermato e impedire l'accesso immediato durante la registrazione, impostare DisplayConfirmAccountLink = false
nel file con scaffolding /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
namespace WebPWrecover.Areas.Identity.Pages.Account
{
[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;
}
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public string Email { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public bool DisplayConfirmAccountLink { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public string EmailConfirmationUrl { get; set; }
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
{
if (email == null)
{
return RedirectToPage("/Index");
}
returnUrl = returnUrl ?? Url.Content("~/");
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();
}
}
}
Questo passaggio è necessario solo quando Account.RegisterConfirmation
viene eseguito lo scaffolding. RegisterConfirmation non sottoposto a scaffolding rileva automaticamente quando un IEmailSender è stato implementato e registrato con il contenitore di inserimento delle dipendenze.
Registrare, confermare la posta elettronica e reimpostare la password
Eseguire l'app Web e testare il flusso di conferma e ripristino delle password dell'account.
- Eseguire l'app e registrare un nuovo utente
- Controllare l'indirizzo di posta elettronica per il collegamento di conferma dell'account. Vedere Eseguire il debug del messaggio di posta elettronica se non si riceve il messaggio di posta elettronica.
- Fare clic sul collegamento per confermare il messaggio di posta elettronica.
- Accedere con l'indirizzo di posta elettronica e la password.
- Disconnettersi.
Testare la reimpostazione della password
- Se è stato eseguito l'accesso, selezionare Disconnetti.
- Selezionare il collegamento Accedi e selezionare il collegamento Password dimenticata?
- Immettere il messaggio di posta elettronica usato per registrare l'account.
- Viene inviato un messaggio di posta elettronica con un collegamento per reimpostare la password. Controllare il messaggio di posta elettronica e fare clic sul collegamento per reimpostare la password. Dopo la reimpostazione della password, è possibile accedere con il messaggio di posta elettronica e la nuova password.
Inviare di nuovo la conferma tramite posta elettronica
In ASP.NET Core 5.0 e versioni successive selezionare il collegamento Invia di nuovo conferma tramite posta elettronica nella pagina Account di accesso .
Modificare il timeout dell'attività e della posta elettronica
Il timeout di inattività predefinito è 14 giorni. Il codice seguente imposta il timeout di inattività su 5 giorni:
services.ConfigureApplicationCookie(o => {
o.ExpireTimeSpan = TimeSpan.FromDays(5);
o.SlidingExpiration = true;
});
Modificare tutta la durata dei token di protezione dei dati
Il codice seguente modifica il periodo di timeout di tutti i token di protezione dei dati a 3 ore:
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();
}
I token utente predefiniti Identity (vedere AspNetCore/src//IdentityExtensions.Core/src/TokenOptions.cs )hanno un timeout di un giorno.
Modificare la durata del token di posta elettronica
La durata del token predefinita dei token utente è un giorno. Identity Questa sezione illustra come modificare la durata del token di posta elettronica.
Aggiungere un oggetto personalizzato DataProtectorTokenProvider<TUser> 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);
}
}
Aggiungere il provider personalizzato al contenitore del servizio:
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();
}
Eseguire il debug della posta elettronica
Se non è possibile ricevere messaggi di posta elettronica funzionanti:
- Impostare un punto di interruzione in
EmailSender.Execute
per verificareSendGridClient.SendEmailAsync
che venga chiamato . - Creare un'app console per inviare messaggi di posta elettronica usando codice simile a
EmailSender.Execute
. - Esaminare la pagina Attività di posta elettronica.
- Controllare la cartella della posta indesiderata.
- Provare un altro alias di posta elettronica su un provider di posta elettronica diverso (Microsoft, Yahoo, Gmail e così via)
- Provare a inviare a account di posta elettronica diversi.
Una procedura consigliata per la sicurezza consiste nel non usare segreti di produzione in fase di test e sviluppo. Se si pubblica l'app in Azure, impostare i segreti SendGrid come impostazioni dell'applicazione nel portale di App Web di Azure. Il sistema di configurazione è configurato per leggere le chiavi dalle variabili di ambiente.
Combinare account di accesso di social network e locali
Per completare questa sezione, è prima necessario abilitare un provider di autenticazione esterno. Vedere Autenticazione del provider esterno, Google e Facebook.
È possibile combinare account locali e social facendo clic sul collegamento di posta elettronica. Nella sequenza seguente "RickAndMSFT@gmail.com" viene prima creato come account di accesso locale. Tuttavia, è possibile creare prima l'account come account di accesso di social networking e quindi aggiungere un account di accesso locale.
Fare clic sul collegamento Gestisci . Si notino i 0 account esterni (account di accesso di social networking) associati a questo account.
Fare clic sul collegamento a un altro servizio di accesso e accettare le richieste dell'app. Nell'immagine seguente Facebook è il provider di autenticazione esterno:
I due conti sono stati combinati. È possibile accedere con uno dei due account. È possibile che gli utenti aggiungano account locali nel caso in cui il servizio di autenticazione dell'account di accesso social sia inattivo o che abbiano perso l'accesso al proprio account di social networking.
Abilitare la conferma dell'account dopo che un sito ha utenti
L'abilitazione della conferma dell'account in un sito con gli utenti blocca tutti gli utenti esistenti. Gli utenti esistenti vengono bloccati perché gli account non vengono confermati. Per aggirare il blocco utente esistente, usare uno degli approcci seguenti:
- Aggiornare il database per contrassegnare tutti gli utenti esistenti come confermati.
- Confermare gli utenti esistenti. Ad esempio, inviare messaggi di posta elettronica in batch con collegamenti di conferma.