ASP.NET Core'da hesap onayı ve parola kurtarma
Rick Anderson, Ponant ve Joe Audette tarafından
Bu öğreticide, e-posta onayı ve parola sıfırlama ile bir ASP.NET Core uygulaması oluşturma işlemi gösterilmektedir. Bu öğretici başlangıç konusu değildir . Aşağıdakiler hakkında bilgi sahibi olmanız gerekir:
Bu makaledeki yönergeleri ekleyen veya yerine geçen yönergeler için Blazor bkz . ASP.NET Core'da Blazorhesap onayı ve parola kurtarma.
Önkoşullar
- .NET Core 6.0 SDK veya üzeri
- C# konsol uygulamasından başarıyla e-posta gönderin.
Kimlik doğrulaması ile web uygulaması oluşturma ve test edin
Kimlik doğrulamasıyla bir web uygulaması oluşturmak için aşağıdaki komutları çalıştırın.
dotnet new webapp -au Individual -o WebPWrecover
cd WebPWrecover
dotnet run
Kullanıcıyı sanal e-posta onayıyla kaydetme
Uygulamayı çalıştırın, Kaydet bağlantısını seçin ve bir kullanıcı kaydedin. Kaydolduktan sonra, e-posta onayını /Identity/Account/RegisterConfirmation
simüle etmek için bir bağlantı içeren sayfaya yönlendirilirsiniz:
Click here to confirm your account
bağlantısını seçin.- Oturum aç bağlantısını seçin ve aynı kimlik bilgileriyle oturum açın.
- Sayfaya
Hello YourEmail@provider.com!
yönlendiren/Identity/Account/Manage/PersonalData
bağlantıyı seçin. - Soldaki Kişisel veriler sekmesini ve ardından Sil'i seçin.
IEmailSender Click here to confirm your account
uygulanmadığından ve bağımlılık ekleme kapsayıcısıyla kaydedilmediğinden bağlantı görüntülenir. RegisterConfirmation
Kaynağa bakın.
Not
.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).
E-posta sağlayıcısı yapılandırma
Bu öğreticide, e-posta göndermek için SendGrid kullanılır. E-posta göndermek için bir SendGrid hesabı ve anahtarı gerekir. SMTP yerine e-posta göndermek için SendGrid veya başka bir e-posta hizmeti kullanmanızı öneririz. SMTP'nin güvenliğini sağlamak ve doğru şekilde ayarlamak zordur.
SendGrid hesabı bir Gönderen eklenmesini gerektirebilir.
Güvenli e-posta anahtarını getirmek için bir sınıf oluşturun. Bu örnek için oluşturun Services/AuthMessageSenderOptions.cs
:
namespace WebPWrecover.Services;
public class AuthMessageSenderOptions
{
public string? SendGridKey { get; set; }
}
SendGrid kullanıcı gizli dizilerini yapılandırma
SendGridKey
gizli dizi yöneticisi aracıyla öğesini ayarlayın. Örneğin:
dotnet user-secrets set SendGridKey <key>
Successfully saved SendGridKey to the secret store.
Windows'da, Gizli Dizi Yöneticisi anahtarları/değer çiftlerini dizindeki bir secrets.json
dosyada %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId>
depolar.
Dosyanın içeriği secrets.json
şifrelenmez. Aşağıdaki işaretlemede dosya gösterilmektedir secrets.json
. Değer SendGridKey
kaldırıldı.
{
"SendGridKey": "<key removed>"
}
Daha fazla bilgi için bkz . Seçenekler düzeni ve yapılandırması.
SendGrid'i yükleme
Bu öğreticide SendGrid aracılığıyla e-posta bildirimlerinin nasıl ekleneceği gösterilmektedir, ancak diğer e-posta sağlayıcıları kullanılabilir.
SendGrid
NuGet paketini yükleyin:
Paket Yöneticisi Konsolu'ndan aşağıdaki komutu girin:
Install-Package SendGrid
Ücretsiz bir SendGrid hesabına kaydolmak için bkz . SendGrid'i Ücretsiz Kullanmaya Başlama.
IEmailSender Uygulama
uygulamak IEmailSender
için aşağıdakine benzer bir kodla oluşturun Services/EmailSender.cs
:
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}");
}
}
Uygulamayı e-postayı destekleyecek şekilde yapılandırma
Program.cs
dosyasına aşağıdaki kodu ekleyin:
- Geçici hizmet olarak ekleyin
EmailSender
. - Yapılandırma örneğini
AuthMessageSenderOptions
kaydedin.
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();
Account.RegisterConfirmation iskelesi yapıldığında varsayılan hesap doğrulamayı devre dışı bırakma
Bu bölüm yalnızca yapı iskelesi yapıldığında Account.RegisterConfirmation
geçerlidir. yapı iskelesi Account.RegisterConfirmation
kurmadıysanız bu bölümü atlayın.
Kullanıcı, hesabın Account.RegisterConfirmation
onaylanması için bir bağlantı seçebileceği konuma yönlendirilir. Varsayılan değer Account.RegisterConfirmation
yalnızca test için kullanılır, üretim uygulamasında otomatik hesap doğrulaması devre dışı bırakılmalıdır.
Onaylanan bir hesap gerektirmek ve kayıt sırasında hemen oturum açmayı önlemek için, iskeledeki /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
dosyada ayarlayınDisplayConfirmAccountLink = false
:
// 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();
}
}
}
Bu adım yalnızca yapı iskelesi yapıldığında Account.RegisterConfirmation
gereklidir. İskeleli olmayan RegisterConfirmation, bir IEmailSender'ın ne zaman uygulandığını ve bağımlılık ekleme kapsayıcısıyla ne zaman kaydedildiğini otomatik olarak algılar.
E-postayı kaydetme, onaylama ve parolayı sıfırlama
Web uygulamasını çalıştırın ve hesap onayını ve parola kurtarma akışını test edin.
- Uygulamayı çalıştırma ve yeni bir kullanıcı kaydetme
- Hesap onay bağlantısı için e-postanızı kontrol edin. E-postayı alamıyorsanız bkz. E-postada hata ayıklama.
- E-postanızı onaylamak için bağlantıya tıklayın.
- E-postanız ve parolanızla oturum açın.
- Oturumu kapatma.
Parola sıfırlamayı test et
- Oturum açtıysanız Oturumu Kapat'ı seçin.
- Oturum aç bağlantısını seçin ve Parolanızı mı unuttunuz? bağlantısını seçin.
- Hesabı kaydetmek için kullandığınız e-postayı girin.
- Parolanızı sıfırlama bağlantısını içeren bir e-posta gönderilir. E-postanızı kontrol edin ve parolanızı sıfırlamak için bağlantıya tıklayın. Parolanız başarıyla sıfırlandıktan sonra e-postanız ve yeni parolanızla oturum açabilirsiniz.
E-posta onaylarını yeniden gönderme
Oturum açma sayfasında E-postayı yeniden gönder onay bağlantısını seçin.
E-posta ve etkinlik zaman aşımını değiştirme
Varsayılan etkinlik dışı zaman aşımı 14 gündür. Aşağıdaki kod etkinlik dışı zaman aşımını 5 güne ayarlar:
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
Tüm veri koruma belirteci kullanım ömrünü değiştirme
Aşağıdaki kod tüm veri koruma belirteçleri zaman aşımı süresini 3 saat olarak değiştirir:
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.
Yerleşik Identity kullanıcı belirteçlerinin (bkz . AspNetCore/src//IdentityExtensions.Core/src/TokenOptions.cs )bir günlük zaman aşımı vardır.
E-posta belirteci kullanım ömrünü değiştirme
Kullanıcı belirteçlerinin Identity varsayılan belirteç ömrü bir gündür. Bu bölümde e-posta belirteci kullanım ömrünün nasıl değiştireceği gösterilmektedir.
Özel DataProtectorTokenProvider<TUser> ve DataProtectionTokenProviderOptionsekleyin:
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);
}
}
Özel sağlayıcıyı hizmet kapsayıcısına ekleyin:
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.
E-posta hatalarını ayıklama
E-postayı çalıştıramıyorsanız:
- çağrıldığını doğrulamak
SendGridClient.SendEmailAsync
için içindeEmailSender.Execute
bir kesme noktası ayarlayın. - ile benzer bir kod kullanarak e-posta göndermek için
EmailSender.Execute
bir konsol uygulaması oluşturun. - E-posta Etkinliği sayfasını gözden geçirin.
- İstenmeyen posta klasörünüzü denetleyin.
- Farklı bir e-posta sağlayıcısında (Microsoft, Yahoo, Gmail vb.) başka bir e-posta diğer adı deneyin
- Farklı e-posta hesaplarına göndermeyi deneyin.
Güvenlik açısından en iyi yöntem, test ve geliştirme aşamasında üretim gizli dizilerini kullanmamaktır. Uygulamayı Azure'da yayımlarsanız, Azure Web App portalında SendGrid gizli dizilerini uygulama ayarları olarak ayarlayın. Yapılandırma sistemi, ortam değişkenlerinden anahtarları okuyacak şekilde ayarlanır.
Sosyal ve yerel oturum açma hesaplarını birleştirme
Bu bölümü tamamlamak için önce bir dış kimlik doğrulama sağlayıcısını etkinleştirmeniz gerekir. Bkz . Facebook, Google ve dış sağlayıcı kimlik doğrulaması.
E-posta bağlantınıza tıklayarak yerel ve sosyal hesapları birleştirebilirsiniz. Aşağıdaki sırayla, "RickAndMSFT@gmail.com" ilk olarak yerel oturum açma olarak oluşturulur; ancak hesabı önce sosyal oturum açma olarak oluşturabilir, ardından yerel oturum açma bilgisi ekleyebilirsiniz.
Yönet bağlantısına tıklayın. Bu hesapla ilişkilendirilmiş 0 harici (sosyal oturum açma bilgileri) not edin.
Başka bir oturum açma hizmetinin bağlantısına tıklayın ve uygulama isteklerini kabul edin. Aşağıdaki görüntüde, Facebook dış kimlik doğrulama sağlayıcısıdır:
İki hesap birleştirildi. İki hesapla da oturum açabilirsiniz. Kullanıcılarınızın sosyal oturum açma kimlik doğrulama hizmetinin çalışmamış olması veya sosyal hesaplarına erişimi kaybetme olasılığı daha yüksek olması durumunda yerel hesaplar eklemesini isteyebilirsiniz.
Bir sitede kullanıcılar olduktan sonra hesap onaylarını etkinleştirme
Kullanıcıların olduğu bir sitede hesap onayını etkinleştirmek, mevcut tüm kullanıcıları kilitler. Hesapları onaylanmamış olduğundan mevcut kullanıcılar kilitlenir. Mevcut kullanıcı kilitlenmesine geçici bir çözüm bulmak için aşağıdaki yaklaşımlardan birini kullanın:
- Veritabanını, var olan tüm kullanıcıları onaylandı olarak işaretlemek için güncelleştirin.
- Mevcut kullanıcıları onaylayın. Örneğin, onay bağlantıları içeren toplu gönderme e-postaları.
Önkoşullar
Kimlik doğrulaması ile web uygulaması oluşturma ve test edin
Kimlik doğrulamasıyla bir web uygulaması oluşturmak için aşağıdaki komutları çalıştırın.
dotnet new webapp -au Individual -uld -o WebPWrecover
cd WebPWrecover
dotnet run
Uygulamayı çalıştırın, Kaydet bağlantısını seçin ve bir kullanıcı kaydedin. Kaydolduktan sonra, e-posta onayını /Identity/Account/RegisterConfirmation
simüle etmek için bir bağlantı içeren sayfaya yönlendirilirsiniz:
Click here to confirm your account
bağlantısını seçin.- Oturum aç bağlantısını seçin ve aynı kimlik bilgileriyle oturum açın.
- Sizi
/Identity/Account/Manage/PersonalData
sayfayaHello YourEmail@provider.com!
yönlendiren bağlantıyı seçin. - Soldaki Kişisel veriler sekmesini ve ardından Sil'i seçin.
E-posta sağlayıcısı yapılandırma
Bu öğreticide, e-posta göndermek için SendGrid kullanılır. Diğer e-posta sağlayıcılarını kullanabilirsiniz. E-posta göndermek için SendGrid veya başka bir e-posta hizmeti kullanmanızı öneririz. SMTP'nin yapılandırılması zordur, bu nedenle posta istenmeyen posta olarak işaretlenmez.
SendGrid hesabı bir Gönderen eklenmesini gerektirebilir.
Güvenli e-posta anahtarını getirmek için bir sınıf oluşturun. Bu örnek için oluşturun Services/AuthMessageSenderOptions.cs
:
namespace WebPWrecover.Services;
public class AuthMessageSenderOptions
{
public string? SendGridKey { get; set; }
}
SendGrid kullanıcı gizli dizilerini yapılandırma
SendGridKey
gizli dizi yöneticisi aracıyla öğesini ayarlayın. Örneğin:
dotnet user-secrets set SendGridKey <SG.key>
Successfully saved SendGridKey = SG.keyVal to the secret store.
Windows'da, Gizli Dizi Yöneticisi anahtarları/değer çiftlerini dizindeki bir secrets.json
dosyada %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId>
depolar.
Dosyanın içeriği secrets.json
şifrelenmez. Aşağıdaki işaretlemede dosya gösterilmektedir secrets.json
. Değer SendGridKey
kaldırıldı.
{
"SendGridKey": "<key removed>"
}
Daha fazla bilgi için bkz . Seçenekler düzeni ve yapılandırması.
SendGrid'i yükleme
Bu öğreticide SendGrid aracılığıyla e-posta bildirimlerinin nasıl ekleneceği gösterilmektedir, ancak SMTP ve diğer mekanizmaları kullanarak e-posta gönderebilirsiniz.
SendGrid
NuGet paketini yükleyin:
Paket Yöneticisi Konsolu'ndan aşağıdaki komutu girin:
Install-Package SendGrid
Ücretsiz bir SendGrid hesabına kaydolmak için bkz . SendGrid'i Ücretsiz Kullanmaya Başlama.
IEmailSender Uygulama
uygulamak IEmailSender
için aşağıdakine benzer bir kodla oluşturun Services/EmailSender.cs
:
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}");
}
}
Başlatmayı e-postayı destekleyecek şekilde yapılandırma
Dosyasındaki yöntemine ConfigureServices
Startup.cs
aşağıdaki kodu ekleyin:
- Geçici hizmet olarak ekleyin
EmailSender
. - Yapılandırma örneğini
AuthMessageSenderOptions
kaydedin.
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();
yapı iskelesi RegisterConfirmation
yapı Identityiskelesi ve iskele Account\RegisterConfirmation
yönergelerini izleyin.
Account.RegisterConfirmation iskelesi yapıldığında varsayılan hesap doğrulamayı devre dışı bırakma
Bu bölüm yalnızca yapı iskelesi yapıldığında Account.RegisterConfirmation
geçerlidir. yapı iskelesi Account.RegisterConfirmation
kurmadıysanız bu bölümü atlayın.
Kullanıcı, hesabın Account.RegisterConfirmation
onaylanması için bir bağlantı seçebileceği konuma yönlendirilir. Varsayılan değer Account.RegisterConfirmation
yalnızca test için kullanılır, üretim uygulamasında otomatik hesap doğrulaması devre dışı bırakılmalıdır.
Onaylanan bir hesap gerektirmek ve kayıt sırasında hemen oturum açmayı önlemek için, iskeledeki /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
dosyada ayarlayınDisplayConfirmAccountLink = false
:
// 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();
}
}
}
Bu adım yalnızca yapı iskelesi yapıldığında Account.RegisterConfirmation
gereklidir. İskeleli olmayan RegisterConfirmation, bir IEmailSender'ın ne zaman uygulandığını ve bağımlılık ekleme kapsayıcısıyla ne zaman kaydedildiğini otomatik olarak algılar.
E-postayı kaydetme, onaylama ve parolayı sıfırlama
Web uygulamasını çalıştırın ve hesap onayını ve parola kurtarma akışını test edin.
- Uygulamayı çalıştırma ve yeni bir kullanıcı kaydetme
- Hesap onay bağlantısı için e-postanızı kontrol edin. E-postayı alamıyorsanız bkz. E-postada hata ayıklama.
- E-postanızı onaylamak için bağlantıya tıklayın.
- E-postanız ve parolanızla oturum açın.
- Oturumu kapatma.
Parola sıfırlamayı test et
- Oturum açtıysanız Oturumu Kapat'ı seçin.
- Oturum aç bağlantısını seçin ve Parolanızı mı unuttunuz? bağlantısını seçin.
- Hesabı kaydetmek için kullandığınız e-postayı girin.
- Parolanızı sıfırlama bağlantısını içeren bir e-posta gönderilir. E-postanızı kontrol edin ve parolanızı sıfırlamak için bağlantıya tıklayın. Parolanız başarıyla sıfırlandıktan sonra e-postanız ve yeni parolanızla oturum açabilirsiniz.
E-posta onaylarını yeniden gönderme
ASP.NET Core 5.0 ve sonraki sürümlerde Oturum Açma sayfasındaki E-postayı yeniden gönder onay bağlantısını seçin.
E-posta ve etkinlik zaman aşımını değiştirme
Varsayılan etkinlik dışı zaman aşımı 14 gündür. Aşağıdaki kod etkinlik dışı zaman aşımını 5 güne ayarlar:
services.ConfigureApplicationCookie(o => {
o.ExpireTimeSpan = TimeSpan.FromDays(5);
o.SlidingExpiration = true;
});
Tüm veri koruma belirteci kullanım ömrünü değiştirme
Aşağıdaki kod tüm veri koruma belirteçleri zaman aşımı süresini 3 saat olarak değiştirir:
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();
}
Yerleşik Identity kullanıcı belirteçlerinin (bkz . AspNetCore/src//IdentityExtensions.Core/src/TokenOptions.cs )bir günlük zaman aşımı vardır.
E-posta belirteci kullanım ömrünü değiştirme
Kullanıcı belirteçlerinin Identity varsayılan belirteç ömrü bir gündür. Bu bölümde e-posta belirteci kullanım ömrünün nasıl değiştireceği gösterilmektedir.
Özel DataProtectorTokenProvider<TUser> ve DataProtectionTokenProviderOptionsekleyin:
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);
}
}
Özel sağlayıcıyı hizmet kapsayıcısına ekleyin:
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();
}
E-posta hatalarını ayıklama
E-postayı çalıştıramıyorsanız:
- çağrıldığını doğrulamak
SendGridClient.SendEmailAsync
için içindeEmailSender.Execute
bir kesme noktası ayarlayın. - ile benzer bir kod kullanarak e-posta göndermek için
EmailSender.Execute
bir konsol uygulaması oluşturun. - E-posta Etkinliği sayfasını gözden geçirin.
- İstenmeyen posta klasörünüzü denetleyin.
- Farklı bir e-posta sağlayıcısında (Microsoft, Yahoo, Gmail vb.) başka bir e-posta diğer adı deneyin
- Farklı e-posta hesaplarına göndermeyi deneyin.
Güvenlik açısından en iyi yöntem, test ve geliştirme aşamasında üretim gizli dizilerini kullanmamaktır. Uygulamayı Azure'da yayımlarsanız, Azure Web App portalında SendGrid gizli dizilerini uygulama ayarları olarak ayarlayın. Yapılandırma sistemi, ortam değişkenlerinden anahtarları okuyacak şekilde ayarlanır.
Sosyal ve yerel oturum açma hesaplarını birleştirme
Bu bölümü tamamlamak için önce bir dış kimlik doğrulama sağlayıcısını etkinleştirmeniz gerekir. Bkz . Facebook, Google ve dış sağlayıcı kimlik doğrulaması.
E-posta bağlantınıza tıklayarak yerel ve sosyal hesapları birleştirebilirsiniz. Aşağıdaki sırayla, "RickAndMSFT@gmail.com" ilk olarak yerel oturum açma olarak oluşturulur; ancak hesabı önce sosyal oturum açma olarak oluşturabilir, ardından yerel oturum açma bilgisi ekleyebilirsiniz.
Yönet bağlantısına tıklayın. Bu hesapla ilişkilendirilmiş 0 harici (sosyal oturum açma bilgileri) not edin.
Başka bir oturum açma hizmetinin bağlantısına tıklayın ve uygulama isteklerini kabul edin. Aşağıdaki görüntüde, Facebook dış kimlik doğrulama sağlayıcısıdır:
İki hesap birleştirildi. İki hesapla da oturum açabilirsiniz. Kullanıcılarınızın sosyal oturum açma kimlik doğrulama hizmetinin çalışmamış olması veya sosyal hesaplarına erişimi kaybetme olasılığı daha yüksek olması durumunda yerel hesaplar eklemesini isteyebilirsiniz.
Bir sitede kullanıcılar olduktan sonra hesap onaylarını etkinleştirme
Kullanıcıların olduğu bir sitede hesap onayını etkinleştirmek, mevcut tüm kullanıcıları kilitler. Hesapları onaylanmamış olduğundan mevcut kullanıcılar kilitlenir. Mevcut kullanıcı kilitlenmesine geçici bir çözüm bulmak için aşağıdaki yaklaşımlardan birini kullanın:
- Veritabanını, var olan tüm kullanıcıları onaylandı olarak işaretlemek için güncelleştirin.
- Mevcut kullanıcıları onaylayın. Örneğin, onay bağlantıları içeren toplu gönderme e-postaları.
ASP.NET Core