Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
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ıç makalesi değildir . Aşağıdakiler hakkında bilgi sahibi olmanız gerekir:
Blazor Bu makaledeki yönergeleri ekleyen veya yerine geçen yönergeler için aşağıdaki kaynaklara bakın:
Önkoşullar
- .NET 6 veya üzeri SDK
- SendGrid API'sini (Twilio) kullanarak C# konsol uygulamasından başarıyla e-posta gönderme
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
Bir 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.
Kayıt tamamlandıktan sonra, e-posta onayı benzetimini /Identity/Account/RegisterConfirmation yapmak için bir bağlantı içeren sayfaya yönlendirilirsiniz.
Click here to confirm your accountbağlantısını seçin.Oturum aç bağlantısını seçin ve aynı kimlik bilgileriyle oturum açın.
/Identity/Account/Manage/PersonalDatasayfasına yönlendirenHello YourEmail@provider.com!bağlantısını seçin.Kişisel veriler sekmesini ve ardından Sil'i seçin.
Click here to confirm your account bağlantısı, IEmailSender arabirimi henüz uygulanmadığı ve bağımlılık enjeksiyonu kapsayıcısına kaydedilmediği için görüntülenir. Daha fazla bilgi için bkz. RegisterConfirmation kaynağı.
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 için bir etiket seçmek üzere Dalları veya etiketleri değiştir açılır 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 Twilio SendGrid kullanılır. E-posta göndermek için bir SendGrid hesabı ve anahtarı gereklidir. 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 Services/AuthMessageSenderOptions.cs dosyasını oluşturun:
namespace WebPWrecover.Services;
public class AuthMessageSenderOptions
{
public string? SendGridKey { get; set; }
}
SendGrid kullanıcı gizli bilgilerini yapılandırın
SendGridKey
Secret-manager aracıyla değeri 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 dizininde %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId> dosyasında depolar.
secrets.json dosyasının içeriği şifrelenmez. Aşağıdaki işaretleme, secrets.json dosyasını gösterir.
SendGridKey Değer örnekten kaldırılır.
{
"SendGridKey": "<key removed>"
}
Daha fazla bilgi için bkz. Seçenekler deseni ve ASP.NET Core’da Yapılandırma.
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 ücretsiz sendGrid E-posta API'sinin deneme sürümüyle göndermeye başlayın.
IEmailSender'ı uygulayın
IEmailSender arabirimini uygulamak için, aşağıdaki örneğe benzer kodla Services/EmailSender.cs dosyasını oluşturun:
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
Aşağıdaki görevleri gerçekleştiren Program.cs dosyasına aşağıdaki kodu ekleyin:
-
EmailSenderÖrneği geçici bir hizmet olarak ekler. -
AuthMessageSenderOptionsyapılandırma örneğini kaydeder.
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 iskeleti oluşturulduğunda varsayılan hesap doğrulamasını devre dışı bırakın
Account.RegisterConfirmation iskeleti oluşturulduysa bu bölümdeki yönergeleri izleyin.
Important
Account.RegisterConfirmation yapı iskelesi kurulmazsa, aşağıdaki yönergeleri atlayın ve sonraki bölüme geçin.
Kullanıcı, hesabın /Identity/Account/RegisterConfirmation onaylanması için bir bağlantı seçebileceği sayfaya yönlendirilir. Varsayılan Account.RegisterConfirmation değer yalnızca test için kullanılır. Otomatik hesap doğrulama bir üretim uygulamasında devre dışı bırakılmalıdır.
Onaylanmış bir hesabı zorunlu kılmak ve kayıt sırasında hemen oturum açılmasını önlemek için, oluşturulan /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs dosyasında DisplayConfirmAccountLink = false ayarını yapın:
// 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 Account.RegisterConfirmation için iskelet oluşturulduğunda gereklidir.
İskele oluşturmayan RegisterConfirmation, bir IEmailSender uygulandığını ve bağımlılık enjeksiyonu kapsayıcısına 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ırın ve yeni bir kullanıcı kaydedin.
Hesap onay bağlantısı için e-postanızı kontrol edin. E-postayı almazsanız sorun giderme için e-posta hatalarını ayıklama bölümüne bakın.
Bağlantıyı seçin ve e-postanızı onaylayın.
E-postanız ve parolanızla oturum açın.
Oturumu kapat.
Parola sıfırlamayı test et
Oturum açtıysanız Oturumu Kapat'ı seçin.
Oturum aç bağlantısını ve ardından Parolanızı mı unuttunuz? bağlantısını seçin.
Hesabı kaydetmek için kullandığınız e-postayı girin. Uygulama, parolanızı sıfırlamak için bir bağlantı içeren bir e-posta gönderir.
Gönderilen e-posta iletisine gidin.
Bağlantıyı seçin ve parolanızı sıfırlayı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
Bu bölümde, e-posta onay işlemini ve ilgili görevleri destekleyen kod açıklanmaktadır.
- Oturum açma sayfasındaki E-postayı yeniden gönder onay bağlantısını seçerek başlayın.
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ı beş 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 için zaman aşımı süresini üç 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 kaynağı) bir günlük zaman aşımı vardır.
E-posta belirteci kullanım ömrünü değiştirme
Identity kullanıcı belirteçlerinin varsayılan kullanım süresi bir gündür.
Aşağıdaki kod, e-posta belirtecinin geçerlilik süresinin nasıl değiştirileceğini gösterir.
Özel DataProtectorTokenProvider<TUser> bir sınıf ve DataProtectionTokenProviderOptions sınıf ekleyin:
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-posta işlemi beklendiği gibi çalışmıyorsa şu sorun giderme adımlarını deneyin:
EmailSender.Executeyönteminde bir kesme noktası ayarlayın veSendGridClient.SendEmailAsyncyönteminin çağrıldığını doğrulayın.ile benzer bir kod kullanarak e-posta göndermek için
EmailSender.Executebir konsol uygulaması oluşturun.E-posta Etkinliği sayfasını gözden geçirin.
İstenmeyen posta klasörünüzü denetleyin.
Microsoft, Yahoo, Gmail gibi farklı bir e-posta sağlayıcısında başka bir e-posta diğer adı deneyin.
Farklı e-posta hesaplarına göndermeyi deneyin.
Tip
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. Daha fazla bilgi için, ASP.NET Core'da Identity ile dış oturum açma sağlayıcıları kullanma bölümüne bakın.
Bu sırada, e-posta adresi RickAndMSFT@gmail.com ilk olarak yerel oturum açma olarak oluşturulur. Ancak önce hesabı sosyal oturum açma olarak oluşturabilir ve ardından yerel oturum açma bilgileri ekleyebilirsiniz.
Yerel ve sosyal hesapları birleştirmek için e-posta adresi bağlantısını seçin.
Hesabınızı yönetin sayfasında Yönet bağlantısını seçin.
Lütfen kimliği doğrulanmış hesapla ilişkili şu anda sıfır (0) harici (sosyal oturum açma yöntemi) bulunduğunu unutmayın.
Dış oturum açma bilgilerinizi yönetin sayfasında başka bir oturum açma hizmetinin bağlantısını seçin. Hizmet istemlerini izleyin ve uygulama isteklerini kabul edin.
Aşağıdaki görüntüde, Facebook bir dış kimlik doğrulama sağlayıcısı olarak eklenir:
Kullanıcı e-posta adresi için kimlik doğrulaması artık yerel ve dış (sosyal) hesapları birleştirir. Kullanıcı iki hesapla da oturum açabilir.
Tip
Kullanıcılarınıza uygulamanıza yerel hesap eklemelerini önermek iyi bir uygulamadır. Bu yaklaşım, sosyal oturum açma kimlik doğrulama hizmetinin devre dışı olması veya sosyal hesaplarına erişimi kaybetmesi durumunda erişimin devam etmesini sağlamaya yardımcı olabilir.
Bir sitede kullanıcılar olduktan sonra hesap onaylarını etkinleştirme
Mevcut kullanıcılarla bir sitede hesap onayını etkinleştirirseniz, hesapları onaylanmamış olduğundan bunları kilitlersiniz.
Mevcut kullanıcı kilitleme sorununu geçici olarak çözmek için aşağıdaki yaklaşımlardan birini kullanın:
Tüm mevcut kullanıcıları onaylandı olarak işaretlemek için veritabanını 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 accountbağlantısını seçin. - Oturum aç bağlantısını seçin ve aynı kimlik bilgileriyle oturum açın.
- Sizi
/Identity/Account/Manage/PersonalDatasayfasına yönlendirenHello YourEmail@provider.com!bağlantısını 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 bilgilerini yapılandırın
secret-manager aracı ile SendGridKey ayarlayın. Örneğin:
dotnet user-secrets set SendGridKey <SG.key>
Successfully saved SendGridKey = SG.keyVal to the secret store.
Windows'ta Secret Manager, anahtar/değer çiftlerini %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId> dizinindeki bir secrets.json dosyasında depolar.
Dosyanın içeriği secrets.json şifrelenmez. Aşağıdaki işaretleme, secrets.json dosyasını gösterir.
SendGridKey değeri 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'ı uygulayın
IEmailSender'ı uygulamak için, aşağıdakine benzer bir kodla Services/EmailSender.cs oluşturun:
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
Startup.cs dosyasındaki ConfigureServices yöntemine aşağıdaki kodu ekleyin:
- Geçici hizmet olarak ekleyin
EmailSender. -
AuthMessageSenderOptionsyapılandırma örneğini 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();
Scaffold Kayıt Onayı
Scaffold Identity ve iskele Account\RegisterConfirmation için yönergeleri izleyin.
Account.RegisterConfirmation iskeleti oluşturulduğunda varsayılan hesap doğrulamasını devre dışı bırakın
Account.RegisterConfirmation iskeleti oluşturulduysa bu bölümdeki yönergeleri izleyin.
Important
Account.RegisterConfirmation yapı iskelesi kurulmazsa, aşağıdaki yönergeleri atlayın ve sonraki bölüme geçin.
Kullanıcı, hesabın /Identity/Account/RegisterConfirmation onaylanması için bir bağlantı seçebileceği sayfaya yönlendirilir. Varsayılan Account.RegisterConfirmation değer yalnızca test için kullanılır. Otomatik hesap doğrulama bir üretim uygulamasında devre dışı bırakılmalıdır.
Onaylanmış bir hesabı zorunlu kılmak ve kayıt sırasında hemen oturum açılmasını önlemek için, oluşturulan /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs dosyasında DisplayConfirmAccountLink = false ayarını yapın:
// 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 Account.RegisterConfirmation için iskelet oluşturulduğunda gereklidir.
İskele oluşturmayan RegisterConfirmation, bir IEmailSender uygulandığını ve bağımlılık enjeksiyonu kapsayıcısına 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ı almazsanız E-posta hata ayıklama bölümüne bakın.
- E-postanızı onaylamak için bağlantıya tıklayın.
- E-postanız ve parolanızla oturum açın.
- Oturumu kapat.
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
.NET 5 veya sonraki sürümlerinde 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:
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/Identity/Extensions.Core/src/TokenOptions.cs) bir günlük zaman aşımı süresi vardır.
E-posta belirteci kullanım ömrünü değiştirme
Identity kullanıcı belirteçlerinin varsayılan kullanım süresi bir gündür. Bu bölüm, e-posta belirtecinin kullanım ömrünün nasıl değiştirileceğini gösterir.
Ö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:
-
SendGridClient.SendEmailAsync'in çağrıldığını doğrulamak içinEmailSender.Executeiçinde bir kesme noktası ayarlayın. - E-posta göndermek için konsol uygulaması oluşturun;
EmailSender.Executeile benzer kod kullanarak. - 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 dış (sosyal oturum açma) olduğunu unutmayın.
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ı.
İlgili içerik
ASP.NET Core