Potwierdzenie konta i odzyskiwanie hasła w usłudze ASP.NET Core Blazor
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
W tym artykule wyjaśniono, jak skonfigurować ASP.NET Core Blazor Web App przy użyciu potwierdzenia wiadomości e-mail i odzyskiwania hasła.
Uwaga
Ten artykuł dotyczy Blazor Web Apptylko s. Aby zaimplementować potwierdzenie wiadomości e-mail i odzyskiwanie haseł dla autonomicznych Blazor WebAssembly aplikacji za pomocą platformy ASP.NET Core Identity, zobacz Potwierdzanie konta i odzyskiwanie hasła w programie ASP.NET Core Blazor WebAssembly za pomocą platformy ASP.NET Core Identity.
Przestrzeń nazw
Przestrzeń nazw aplikacji używana przez przykład w tym artykule to BlazorSample
. Zaktualizuj przykłady kodu, aby używać przestrzeni nazw aplikacji.
Wybieranie i konfigurowanie dostawcy poczty e-mail
W tym artykule interfejs API transakcyjny mailchimpa jest używany za pośrednictwem Mandrill.net do wysyłania wiadomości e-mail. Zalecamy używanie usługi poczty e-mail do wysyłania wiadomości e-mail zamiast SMTP. Protokół SMTP jest trudny do prawidłowego konfigurowania i zabezpieczania. Niezależnie od używanej usługi poczty e-mail uzyskaj dostęp do wskazówek dotyczących aplikacji platformy .NET, utwórz konto, skonfiguruj klucz interfejsu API dla swojej usługi i zainstaluj wymagane pakiety NuGet.
Utwórz klasę do przechowywania klucza interfejsu API tajnego dostawcy poczty e-mail. W przykładzie w tym artykule użyto klasy o nazwie AuthMessageSenderOptions
z właściwością EmailAuthKey
do przechowywania klucza.
AuthMessageSenderOptions.cs
:
namespace BlazorSample;
public class AuthMessageSenderOptions
{
public string? EmailAuthKey { get; set; }
}
AuthMessageSenderOptions
Zarejestruj wystąpienie konfiguracji w Program
pliku:
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
Konfigurowanie wpisu tajnego użytkownika dla klucza zabezpieczeń dostawcy
Jeśli projekt został już zainicjowany dla narzędzia Secret Manager, będzie on już miał identyfikator wpisów tajnych aplikacji () w pliku projektu (.csproj
<AppSecretsId>
). W programie Visual Studio możesz określić, czy identyfikator wpisów tajnych aplikacji jest obecny, przeglądając panel Właściwości po wybraniu projektu w Eksplorator rozwiązań. Jeśli aplikacja nie została zainicjowana, wykonaj następujące polecenie w powłoce poleceń otwartej w katalogu projektu. W programie Visual Studio możesz użyć wiersza polecenia Programu PowerShell dla deweloperów.
dotnet user-secrets init
Ustaw klucz interfejsu API za pomocą narzędzia Secret Manager. W poniższym przykładzie nazwa klucza jest EmailAuthKey
zgodna AuthMessageSenderOptions.EmailAuthKey
z symbolem zastępczym , a klucz jest reprezentowany {KEY}
przez symbol zastępczy. Wykonaj następujące polecenie za pomocą klucza interfejsu API:
dotnet user-secrets set "EmailAuthKey" "{KEY}"
Jeśli używasz programu Visual Studio, możesz potwierdzić, że wpis tajny został ustawiony, klikając prawym przyciskiem myszy projekt serwera w Eksplorator rozwiązań i wybierając polecenie Zarządzaj wpisami tajnymi użytkownika.
Aby uzyskać więcej informacji, zobacz Bezpieczny magazyn wpisów tajnych aplikacji w programowaniu w usłudze ASP.NET Core.
Ostrzeżenie
Nie przechowuj wpisów tajnych aplikacji, parametry połączenia, poświadczeń, haseł, osobistych numerów identyfikacyjnych (PIN), prywatnego kodu C#/.NET lub kluczy prywatnych/tokenów w kodzie po stronie klienta, który jest zawsze niepewny. W środowiskach testowych/przejściowych i produkcyjnych kod po stronie Blazor serwera i internetowe interfejsy API powinny używać bezpiecznych przepływów uwierzytelniania, które unikają utrzymywania poświadczeń w kodzie projektu lub plikach konfiguracji. Poza lokalnymi testami programistycznymi zalecamy unikanie używania zmiennych środowiskowych do przechowywania poufnych danych, ponieważ zmienne środowiskowe nie są najbezpieczniejszym podejściem. W przypadku lokalnego testowania programistycznego narzędzie Secret Manager jest zalecane do zabezpieczania poufnych danych. Aby uzyskać więcej informacji, zobacz Bezpieczne utrzymywanie poufnych danych i poświadczeń.
Narzędzie IEmailSender
Poniższy przykład jest oparty na interfejsie API transakcyjnym Mailchimp przy użyciu Mandrill.net. W przypadku innego dostawcy zapoznaj się z dokumentacją dotyczącą implementowania wysyłania wiadomości e-mail.
Dodaj pakiet Mandrill.net NuGet do projektu.
Dodaj następującą EmailSender
klasę, aby zaimplementować element IEmailSender<TUser>. W poniższym przykładzie ApplicationUser
jest to IdentityUser. Adiustacja HTML komunikatu może być dodatkowo dostosowywana. O ile przekazany MandrillMessage
element message
zaczyna się od <
znaku, interfejs API Mandrill.net zakłada, że treść komunikatu jest skomponowana w kodzie 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);
}
}
Uwaga
Zawartość treści wiadomości może wymagać specjalnego kodowania dla dostawcy usługi poczty e-mail. Jeśli nie można wykonać linków w treści wiadomości e-mail, zapoznaj się z dokumentacją dostawcy usług, aby rozwiązać ten problem.
Konfigurowanie aplikacji do obsługi poczty e-mail
Program
W pliku zmień implementację nadawcy wiadomości e-mail na :EmailSender
- builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
+ builder.Services.AddSingleton<IEmailSender<ApplicationUser>, EmailSender>();
Usuń element IdentityNoOpEmailSender
(Components/Account/IdentityNoOpEmailSender.cs
) z aplikacji.
W składniku RegisterConfirmation
(Components/Account/Pages/RegisterConfirmation.razor
) usuń blok warunkowy w @code
bloku, który sprawdza, czy EmailSender
element to IdentityNoOpEmailSender
:
- else if (EmailSender is IdentityNoOpEmailSender)
- {
- ...
- }
Ponadto w składniku RegisterConfirmation
usuń Razor znaczniki i kod sprawdzania emailConfirmationLink
pola, pozostawiając tylko wiersz instruujący użytkownika, aby sprawdzić swoją wiadomość e-mail...
- @if (emailConfirmationLink is not null)
- {
- ...
- }
- else
- {
<p>Please check your email to confirm your account.</p>
- }
@code {
- private string? emailConfirmationLink;
...
}
Włączanie potwierdzenia konta po tym, jak witryna ma użytkowników
Włączanie potwierdzenia konta w witrynie z użytkownikami blokuje wszystkich istniejących użytkowników. Istniejący użytkownicy są zablokowani, ponieważ ich konta nie są potwierdzane. Aby obejść istniejącą blokadę użytkownika, użyj jednej z następujących metod:
- Zaktualizuj bazę danych, aby oznaczyć wszystkich istniejących użytkowników zgodnie z potwierdzeniem.
- Potwierdź istniejących użytkowników. Na przykład wiadomości e-mail wysyłane wsadowo z linkami potwierdzenia.
Limit czasu wiadomości e-mail i aktywności
Domyślny limit czasu braku aktywności wynosi 14 dni. Poniższy kod ustawia limit czasu braku aktywności na pięć dni z przesuwanym wygaśnięciem:
builder.Services.ConfigureApplicationCookie(options => {
options.ExpireTimeSpan = TimeSpan.FromDays(5);
options.SlidingExpiration = true;
});
Zmiana wszystkich cykli życia tokenu ASP.NET Core Data Protection
Poniższy kod zmienia limit czasu tokenów ochrony danych na trzy godziny:
builder.Services.Configure<DataProtectionTokenProviderOptions>(options =>
options.TokenLifespan = TimeSpan.FromHours(3));
Wbudowane Identity tokeny użytkownika (AspNetCore/src//IdentityExtensions.Core/src/TokenOptions.cs) mają jednorazowy limit czasu.
Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Zmienianie cyklu życia tokenu poczty e-mail
Domyślna żywotność tokenów Identity użytkownika wynosi jeden dzień.
Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Aby zmienić cykl życia tokenu poczty e-mail, dodaj element niestandardowy DataProtectorTokenProvider<TUser> i 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);
}
}
Skonfiguruj usługi tak, aby korzystały z niestandardowego dostawcy tokenów Program
w pliku:
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>>();
Rozwiązywanie problemów
Jeśli nie możesz uzyskać wiadomości e-mail, działa:
- Ustaw punkt przerwania w ,
EmailSender.Execute
aby zweryfikowaćSendEmailAsync
, jest wywoływany. - Utwórz aplikację konsolową do wysyłania wiadomości e-mail przy użyciu kodu podobnego do
EmailSender.Execute
debugowania problemu. - Przejrzyj strony historii poczty e-mail konta w witrynie internetowej dostawcy poczty e-mail.
- Sprawdź folder spamu pod kątem wiadomości.
- Spróbuj użyć innego aliasu poczty e-mail u innego dostawcy poczty e-mail, takiego jak Microsoft, Yahoo lub Gmail.
- Spróbuj wysłać do różnych kont e-mail.