Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
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. Questo tutorial non è un articolo per principianti. È necessario avere familiarità con:
Per Blazor indicazioni su come aggiungere o sostituire le linee guida contenute in questo articolo, vedere le risorse seguenti:
Prerequisiti
- SDK .NET 6 o versione successiva
- Inviare correttamente email da un'app console C# usando l'API SendGrid (Twilio)
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 un utente con conferma tramite posta elettronica simulata
Eseguire l'app, selezionare il collegamento Registra e registrare un utente.
Al termine della registrazione, si viene reindirizzati alla /Identity/Account/RegisterConfirmation pagina, che contiene un collegamento per simulare la conferma tramite posta elettronica.
Selezionare il collegamento
Click here to confirm your account.Selezionare il link Login ed effettuare l'accesso con le stesse credenziali.
Selezionare il
Hello YourEmail@provider.com!collegamento che reindirizza alla/Identity/Account/Manage/PersonalDatapagina.Selezionare la scheda Dati personali e quindi selezionare Elimina.
Il Click here to confirm your account collegamento viene visualizzato perché l'interfaccia IEmailSender non è ancora implementata e registrata con il contenitore di dependency injection. Per ulteriori informazioni, vedere il codice sorgente RegisterConfirmation.
Nota
I collegamenti della documentazione al codice sorgente di riferimento di .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la prossima versione di .NET. Per selezionare un tag per una versione specifica, utilizza il menu 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, Twilio 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 il file Services/AuthMessageSenderOptions.cs :
namespace WebPWrecover.Services;
public class AuthMessageSenderOptions
{
public string? SendGridKey { get; set; }
}
Configurare i segreti utente di SendGrid
Imposta SendGridKey valore utilizzando lo strumento secret-manager. Ad esempio:
dotnet user-secrets set SendGridKey <key>
Successfully saved SendGridKey to the secret store.
In Windows Secret Manager archivia le coppie chiavi/valore in un file secrets.json nella directory %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId>.
Il contenuto del filesecrets.json non è crittografato. Il markup seguente illustra il file secrets.json . Il SendGridKey valore viene rimosso dall'esempio.
{
"SendGridKey": "<key removed>"
}
Per altre informazioni, vedere il modello Options e Configuration in ASP.NET Core.
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
Per registrarsi per un account SendGrid gratuito, iniziare a inviare con una versione di valutazione gratuita dell'API SendGrid Email.
Implementare IEmailSender
Per implementare l'interfaccia IEmailSender , creare il file Services/EmailSender.cs con codice simile all'esempio 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 , che esegue le attività seguenti:
- Aggiunge l'istanza
EmailSendercome servizio temporaneo. - Registra l'istanza di configurazione
AuthMessageSenderOptions.
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 predefinita dell'account quando Account.RegisterConfirmation viene generato tramite scaffolding
Se Account.RegisterConfirmation è stato generato tramite scaffolding, completare le istruzioni in questa sezione.
Important
Se Account.RegisterConfirmationnon è stato eseguito lo scaffolding, ignorare le istruzioni seguenti e continuare con la sezione successiva.
L'utente viene reindirizzato alla /Identity/Account/RegisterConfirmation pagina in cui è possibile selezionare un collegamento per confermare l'account. Il valore predefinito Account.RegisterConfirmation viene usato solo per i test. La verifica automatica dell'account deve essere disabilitata in un'app di produzione.
Per richiedere un account confermato e impedire l'accesso immediato al momento della registrazione, impostare DisplayConfirmAccountLink = false nel file /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs generato tramite scaffolding:
// 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 generato mediante scaffolding.
RegisterConfirmation non sottoposto a scaffolding rileva automaticamente quando un IEmailSender viene 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. Se non si riceve il messaggio di posta elettronica, vedere la sezione Debug e-mail per la risoluzione dei problemi.
Selezionare il collegamento e 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 quindi selezionare il collegamento Password dimenticata?
Immettere il messaggio di posta elettronica usato per registrare l'account. L'app invia un messaggio di posta elettronica con un collegamento per reimpostare la password.
Passare al messaggio di posta elettronica inviato.
Selezionare il collegamento e 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
Questa sezione descrive il codice che supporta il processo di conferma tramite posta elettronica e le attività correlate.
- Per iniziare, selezionare il collegamento Invia di nuovo conferma tramite posta elettronica nella pagina Di accesso .
Modifica il timeout dell'email e dell'attività
Il timeout di inattività predefinito è 14 giorni. Il codice seguente imposta il timeout di inattività su cinque 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 per tutti i token di protezione dei dati a tre 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 l'origine AspNetCore/src/Identity/Extensions.Core/src/TokenOptions.cs ) hanno un timeout di un giorno.
Modificare la durata del token di posta elettronica
La durata predefinita dei token Identity utente è di un giorno.
Il codice seguente illustra come modificare la durata del token di posta elettronica.
Aggiungi una classe personalizzata DataProtectorTokenProvider<TUser> e una classe personalizzata 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 il processo di posta elettronica non funziona come previsto, provare a seguire questa procedura di risoluzione dei problemi:
Impostare un punto di interruzione nel
EmailSender.Executemetodo e verificare che venga chiamato ilSendGridClient.SendEmailAsyncmetodo .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, ad esempio Microsoft, Yahoo, Gmail e così via.
Provare a inviare a account di posta elettronica diversi.
Tip
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.
Combinazione di account di accesso social e locali
Per completare questa sezione, è prima necessario abilitare un provider di autenticazione esterno. Per maggiori informazioni, vedere Utilizzare i provider di accesso esterni con Identity in ASP.NET Core.
In questa sequenza, l'indirizzo RickAndMSFT@gmail.com di posta elettronica 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.
Per combinare account locali e social, seleziona il collegamento dell'indirizzo e-mail.
Nella pagina Gestisci l'account selezionare il collegamento Gestisci .
Si noti che all'account autenticato sono attualmente associati zero (0) esterni (account di accesso social).
Nella pagina Gestisci account di accesso esterni selezionare il collegamento a un altro servizio di accesso. Seguire le richieste del servizio e accettare le richieste dell'app.
Nell'immagine seguente Facebook viene aggiunto come provider di autenticazione esterno:
L'autenticazione per l'indirizzo di posta elettronica dell'utente ora combina account locali ed esterni (social). L'utente può accedere con uno dei due account.
Tip
È consigliabile consigliare agli utenti di aggiungere un account locale all'app. Questo approccio può contribuire a garantire un accesso continuativo nel caso in cui il servizio di autenticazione dell'accesso social non sia disponibile oppure si perda l'accesso al proprio account social.
Abilitare la conferma dell'account dopo che un sito ha utenti
Se si abilita la conferma dell'account su un sito con utenti esistenti, si impedisce loro l'accesso perché i loro account non sono confermati.
Per risolvere il problema del 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 o versione successiva SDK
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 /Identity/Account/RegisterConfirmation, che contiene un collegamento per simulare la conferma dell’e-mail:
- Selezionare il collegamento
Click here to confirm your account. - Selezionare il link Login ed effettuare l'accesso con le stesse credenziali.
- Selezionare il
Hello YourEmail@provider.com!collegamento, che reindirizza alla/Identity/Account/Manage/PersonalDatapagina. - 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
Imposta il SendGridKey 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
EmailSendercome servizio temporaneo. - Registrare l'istanza di configurazione
AuthMessageSenderOptions.
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();
Impalcatura ConfermaRegistrazione
Seguire le istruzioni per Scaffold Identity e scaffold Account\RegisterConfirmation.
Disabilitare la verifica predefinita dell'account quando Account.RegisterConfirmation viene generato tramite scaffolding
Se Account.RegisterConfirmation è stato generato tramite scaffolding, completare le istruzioni in questa sezione.
Important
Se Account.RegisterConfirmationnon è stato eseguito lo scaffolding, ignorare le istruzioni seguenti e continuare con la sezione successiva.
L'utente viene reindirizzato alla /Identity/Account/RegisterConfirmation pagina in cui è possibile selezionare un collegamento per confermare l'account. Il valore predefinito Account.RegisterConfirmation viene usato solo per i test. La verifica automatica dell'account deve essere disabilitata in un'app di produzione.
Per richiedere un account confermato e impedire l'accesso immediato al momento della registrazione, impostare DisplayConfirmAccountLink = false nel file /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs generato tramite scaffolding:
// 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 generato mediante scaffolding.
RegisterConfirmation non sottoposto a scaffolding rileva automaticamente quando un IEmailSender viene 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 .NET 5 o versione successiva selezionare il collegamento Invia di nuovo conferma tramite posta elettronica nella pagina Di accesso .
Modifica il timeout dell'email e dell'attività
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 predefinita dei token Identity utente è di un giorno. 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:
- Imposta un breakpoint in
EmailSender.Executeper verificare cheSendGridClient.SendEmailAsyncvenga 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.
Associare account di accesso tramite social network e account locali
Per completare questa sezione, è prima necessario abilitare un provider di autenticazione esterno. Vedere Facebook, Google e autenticazione del provider esterno.
È 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 . Nota i 0 accessi esterni (accessi social) 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. Potresti voler consentire ai tuoi utenti di aggiungere account locali nel caso in cui il servizio di autenticazione tramite social login non sia disponibile o, più probabilmente, abbiano perso l'accesso al proprio account social.
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.