Potvrzení účtu a obnovení hesla v ASP.NET Core Blazor
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Tento článek vysvětluje, jak nakonfigurovat ASP.NET Core Blazor Web App s potvrzením e-mailu a obnovením hesla.
Poznámka:
Tento článek se týká Blazor Web Apppouze s. Pokud chcete implementovat potvrzení e-mailu a obnovení hesla pro samostatné Blazor WebAssembly aplikace s ASP.NET Core Identity, přečtěte si informace o potvrzení účtu a obnovení hesla v ASP.NET Core Blazor WebAssembly s ASP.NET Core Identity.
Obor názvů
Obor názvů aplikace používaný v příkladu v tomto článku je BlazorSample
. Aktualizujte příklady kódu tak, aby používaly obor názvů vaší aplikace.
Výběr a konfigurace poskytovatele e-mailu
V tomto článku se k odesílání e-mailů používá transakční rozhraní API mailchimpu prostřednictvím Mandrill.net . K odesílání e-mailů místo SMTP doporučujeme použít e-mailovou službu. Konfigurace a zabezpečení protokolu SMTP je obtížné. Bez ohledu na to, kterou e-mailovou službu používáte, získejte přístup k pokynům pro aplikace .NET, vytvořte účet, nakonfigurujte klíč rozhraní API pro svou službu a nainstalujte všechny požadované balíčky NuGet.
Vytvořte třídu pro uložení klíče rozhraní API zprostředkovatele tajných e-mailů. Příklad v tomto článku používá třídu pojmenovanou AuthMessageSenderOptions
EmailAuthKey
s vlastností k uložení klíče.
AuthMessageSenderOptions.cs
:
namespace BlazorSample;
public class AuthMessageSenderOptions
{
public string? EmailAuthKey { get; set; }
}
AuthMessageSenderOptions
Zaregistrujte instanci konfigurace v Program
souboru:
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
Konfigurace tajného klíče uživatele pro klíč zabezpečení poskytovatele
Pokud už byl projekt inicializován pro nástroj Secret Manager, bude už mít v souboru projektu identifikátor tajných kódů aplikace (<AppSecretsId>
.csproj
). V sadě Visual Studio zjistíte, jestli id tajných kódů aplikace existuje, a to tak, že se podíváte na panel Vlastnosti, když je projekt vybraný v Průzkumník řešení. Pokud aplikace nebyla inicializována, spusťte v příkazovém prostředí otevřeném v adresáři projektu následující příkaz. V sadě Visual Studio můžete použít příkazový řádek Developer PowerShellu.
dotnet user-secrets init
Nastavte klíč rozhraní API pomocí nástroje Secret Manager. V následujícím příkladu se název klíče shoduje EmailAuthKey
AuthMessageSenderOptions.EmailAuthKey
a klíč je reprezentován zástupným {KEY}
symbolem. Spusťte následující příkaz s klíčem rozhraní API:
dotnet user-secrets set "EmailAuthKey" "{KEY}"
Pokud používáte Visual Studio, můžete ověřit, že je tajný kód nastavený tak, že v Průzkumník řešení kliknete pravým tlačítkem na projekt serveru a vyberete Spravovat tajné kódy uživatelů.
Další informace najdete v tématu Bezpečné ukládání tajných kódů aplikací při vývoji v ASP.NET Core.
Upozorňující
Neukládejte tajné kódy aplikací, připojovací řetězec, přihlašovací údaje, hesla, osobní identifikační čísla (PIN), privátní kód C#/.NET nebo privátní klíče/tokeny v kódu na straně klienta, což je vždy nezabezpečené. V testovacích a pracovních a produkčních prostředích by kód na straně Blazor serveru a webová rozhraní API měly používat toky zabezpečeného ověřování, které se vyhýbají údržbě přihlašovacích údajů v kódu projektu nebo konfiguračních souborech. Mimo místní testování vývoje doporučujeme vyhnout se použití proměnných prostředí k ukládání citlivých dat, protože proměnné prostředí nejsou nejbezpečnějším přístupem. Pro místní testování vývoje se pro zabezpečení citlivých dat doporučuje nástroj Secret Manager. Další informace najdete v tématu Bezpečné udržování citlivých dat a přihlašovacích údajů.
Implementovat IEmailSender
Následující příklad je založený na transakčním rozhraní API mailchimpu pomocí Mandrill.net. Informace o tom, jak implementovat odesílání e-mailových zpráv, najdete v dokumentaci jiného poskytovatele.
Přidejte do projektu balíček NuGet Mandrill.net .
Přidejte následující EmailSender
třídu pro implementaci IEmailSender<TUser>. V následujícím příkladu ApplicationUser
je .IdentityUser Kód HTML zprávy lze dále přizpůsobit. Pokud message
MandrillMessage
předání začíná znakem <
, Mandrill.net ROZHRANÍ API předpokládá, že text zprávy se skládá v HTML.
Components/Account/EmailSender.cs
:
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Mandrill;
using Mandrill.Model;
using BlazorSample.Data;
namespace BlazorSample.Components.Account;
public class EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor,
ILogger<EmailSender> logger) : IEmailSender<ApplicationUser>
{
private readonly ILogger logger = logger;
public AuthMessageSenderOptions Options { get; } = optionsAccessor.Value;
public Task SendConfirmationLinkAsync(AppUser user, string email,
string confirmationLink) => SendEmailAsync(email, "Confirm your email",
"<html lang=\"en\"><head></head><body>Please confirm your account by " +
$"<a href='{confirmationLink}'>clicking here</a>.</body></html>");
public Task SendPasswordResetLinkAsync(AppUser user, string email,
string resetLink) => SendEmailAsync(email, "Reset your password",
"<html lang=\"en\"><head></head><body>Please reset your password by " +
$"<a href='{resetLink}'>clicking here</a>.</body></html>");
public Task SendPasswordResetCodeAsync(AppUser user, string email,
string resetCode) => SendEmailAsync(email, "Reset your password",
"<html lang=\"en\"><head></head><body>Please reset your password " +
$"using the following code:<br>{resetCode}</body></html>");
public async Task SendEmailAsync(string toEmail, string subject, string message)
{
if (string.IsNullOrEmpty(Options.EmailAuthKey))
{
throw new Exception("Null EmailAuthKey");
}
await Execute(Options.EmailAuthKey, subject, message, toEmail);
}
public async Task Execute(string apiKey, string subject, string message,
string toEmail)
{
var api = new MandrillApi(apiKey);
var mandrillMessage = new MandrillMessage("sarah@contoso.com", toEmail,
subject, message);
await api.Messages.SendAsync(mandrillMessage);
logger.LogInformation("Email to {EmailAddress} sent!", toEmail);
}
}
Poznámka:
Základní obsah zpráv může vyžadovat speciální kódování pro poskytovatele e-mailové služby. Pokud odkazy v textu zprávy nelze v e-mailové zprávě sledovat, obraťte se na dokumentaci poskytovatele služeb a problém vyřešte.
Konfigurace aplikace pro podporu e-mailu
Program
V souboru změňte implementaci odesílatele e-mailu na EmailSender
:
- builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
+ builder.Services.AddSingleton<IEmailSender<ApplicationUser>, EmailSender>();
IdentityNoOpEmailSender
Odeberte (Components/Account/IdentityNoOpEmailSender.cs
) z aplikace.
V komponentě RegisterConfirmation
(Components/Account/Pages/RegisterConfirmation.razor
) odeberte podmíněný blok v @code
bloku, který zkontroluje, zda EmailSender
je IdentityNoOpEmailSender
:
- else if (EmailSender is IdentityNoOpEmailSender)
- {
- ...
- }
Také v komponentě RegisterConfirmation
odeberte značky Razor a kód pro kontrolu emailConfirmationLink
pole a ponechte jen řádek s pokynem uživateli, aby zkontroloval svůj e-mail ...
- @if (emailConfirmationLink is not null)
- {
- ...
- }
- else
- {
<p>Please check your email to confirm your account.</p>
- }
@code {
- private string? emailConfirmationLink;
...
}
Povolení potvrzení účtu po tom, co má web uživatele
Povolení potvrzení účtu na webu s uživateli zamkne všechny stávající uživatele. Stávající uživatelé jsou uzamčení, protože jejich účty se nepotvrdí. Pokud chcete obejít stávající uzamčení uživatele, použijte jeden z následujících přístupů:
- Aktualizujte databázi tak, aby označí všechny existující uživatele jako potvrzené.
- Potvrďte existující uživatele. Například dávkové odesílání e-mailů s potvrzovanými odkazy.
Vypršení časového limitu e-mailu a aktivity
Výchozí časový limit nečinnosti je 14 dnů. Následující kód nastaví časový limit nečinnosti na pět dnů s posuvným vypršením platnosti:
builder.Services.ConfigureApplicationCookie(options => {
options.ExpireTimeSpan = TimeSpan.FromDays(5);
options.SlidingExpiration = true;
});
Změna všech životností tokenů ochrany dat core ASP.NET
Následující kód změní časový limit tokenů ochrany dat na tři hodiny:
builder.Services.Configure<DataProtectionTokenProviderOptions>(options =>
options.TokenLifespan = TimeSpan.FromHours(3));
Předdefinované Identity uživatelské tokeny (AspNetCore/src/Identity/Extensions.Core/src/TokenOptions.cs) mají časový limit jednoho dne.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Změna životnosti e-mailového tokenu
Výchozí životnost Identity tokenů uživatele je jeden den.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Pokud chcete změnit životnost e-mailového tokenu, přidejte vlastní DataProtectorTokenProvider<TUser> a DataProtectionTokenProviderOptions.
CustomTokenProvider.cs
:
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
namespace BlazorSample;
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);
}
}
public class CustomPasswordResetTokenProvider<TUser>
: DataProtectorTokenProvider<TUser> where TUser : class
{
public CustomPasswordResetTokenProvider(
IDataProtectionProvider dataProtectionProvider,
IOptions<PasswordResetTokenProviderOptions> options,
ILogger<DataProtectorTokenProvider<TUser>> logger)
: base(dataProtectionProvider, options, logger)
{
}
}
public class PasswordResetTokenProviderOptions :
DataProtectionTokenProviderOptions
{
public PasswordResetTokenProviderOptions()
{
Name = "PasswordResetDataProtectorTokenProvider";
TokenLifespan = TimeSpan.FromHours(3);
}
}
Nakonfigurujte služby tak, aby používaly vlastního zprostředkovatele tokenu Program
v souboru:
builder.Services.AddIdentityCore<ApplicationUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.Tokens.ProviderMap.Add("CustomEmailConfirmation",
new TokenProviderDescriptor(
typeof(CustomEmailConfirmationTokenProvider<ApplicationUser>)));
options.Tokens.EmailConfirmationTokenProvider =
"CustomEmailConfirmation";
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddSignInManager()
.AddDefaultTokenProviders();
builder.Services
.AddTransient<CustomEmailConfirmationTokenProvider<ApplicationUser>>();
Odstraňování potíží
Pokud vám nefunguje e-mail:
- Nastavte zarážku
EmailSender.Execute
pro ověřeníSendEmailAsync
. - Vytvořte konzolovou aplikaci pro odesílání e-mailů pomocí kódu podobného
EmailSender.Execute
ladění problému. - Zkontrolujte stránky historie e-mailů účtu na webu poskytovatele e-mailu.
- Zkontrolujte, jestli ve složce spamu nezískáte zprávy.
- Zkuste jiný e-mailový alias u jiného poskytovatele e-mailu, jako je Microsoft, Yahoo nebo Gmail.
- Zkuste odeslat do různých e-mailových účtů.