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.
Tarafından Hao Kung, Pranav Rastogi, Rick Anderson, Suhas Joshi
Bu öğreticide, SMS ve e-posta kullanarak İki öğeli kimlik doğrulamasını (2FA) nasıl ayarlayacağınız gösterilir.
Bu makale Rick Anderson (@RickAndMSFT), Pranav Rastogi (@rustd), Hao Kung ve Suhas Joshi tarafından yazılmıştır. NuGet örneği öncelikle Hao Kung tarafından yazılmıştır.
Bu konu aşağıdaki konuları kapsar:
- Kimlik örneğini oluşturma
- İki öğeli kimlik doğrulaması için SMS'i ayarlama
- İki öğeli kimlik doğrulamasını etkinleştirme
- İki öğeli kimlik doğrulama sağlayıcısını kaydetme
- Sosyal ve yerel oturum açma hesaplarını birleştirme
- Deneme yanılma saldırılarından hesap kilitlenmesi
Kimlik örneğini oluşturma
Bu bölümde, birlikte çalışacağımız bir örneği indirmek için NuGet kullanacaksınız. Web veya Visual Studio 2013 için Visual Studio Express 2013'i yükleyip çalıştırarak başlayın. Visual Studio 2013 Güncelleştirme 2 veya üzerini yükleyin.
Not
Uyarı: Bu öğreticiyi tamamlamak için Visual Studio 2013 Güncelleştirme 2'yi yüklemeniz gerekir.
Yeni bir boş ASP.NET Web projesi oluşturun.
Paket Yöneticisi Konsolu'nda aşağıdaki komutları girin:
Install-Package SendGrid
Install-Package -Prerelease Microsoft.AspNet.Identity.SamplesBu öğreticide, e-posta göndermek için SendGrid'i ve sms mesajları için Twilio veya ASPSMS'yi kullanacağız. Paket
Identity.Samples, üzerinde çalışacağımız kodu yükler.Projeyi SSL kullanacak şekilde ayarlayın.
İsteğe bağlı: SendGrid'i bağlayıp uygulamayı çalıştırıp bir e-posta hesabı kaydetmek için Email onay öğreticimdeki yönergeleri izleyin.
Isteğe bağlı: Örnekten tanıtım e-posta bağlantısı onay kodunu kaldırın (
ViewBag.LinkHesap denetleyicisindeki kod. veForgotPasswordConfirmationeylem yöntemlerineDisplayEmailve razor görünümlerine bakın.Isteğe bağlı:
ViewBag.StatusKodu Yönet ve Hesap denetleyicilerinden ve Views\Account\VerifyCode.cshtml ve Views\Manage\VerifyPhoneNumber.cshtml razor görünümlerinden kaldırın. Alternatif olarak, bu uygulamanın yerel olarak nasıl çalıştığını test etmek için e-posta ve SMS mesajları göndermek zorunda kalmadan ekranı koruyabilirsinizViewBag.Status.
Not
Uyarı: Bu örnekteki güvenlik ayarlarından herhangi birini değiştirirseniz, üretim uygulamalarının yapılan değişiklikleri açıkça çağıran bir güvenlik denetiminden geçmesi gerekir.
İki öğeli kimlik doğrulaması için SMS'i ayarlama
Bu öğreticide Twilio veya ASPSMS kullanma yönergeleri sağlanır, ancak başka herhangi bir SMS sağlayıcısını kullanabilirsiniz.
SMS sağlayıcısı ile Kullanıcı Hesabı Oluşturma
Ek paketleri yükleme veya hizmet başvuruları ekleme
Twilio:
Paket Yöneticisi Konsolu'nda aşağıdaki komutu girin:
Install-Package TwilioASPSMS:
Aşağıdaki hizmet başvurusunun eklenmesi gerekir:
Adres:
https://webservice.aspsms.com/aspsmsx2.asmx?WSDLAd alanı:
ASPSMSX2SMS Sağlayıcısı Kullanıcı kimlik bilgilerini anlama
Twilio:
Twilio hesabınızın Pano sekmesinde Hesap SID'sini ve Kimlik Doğrulama belirtecini kopyalayın.ASPSMS:
Hesap ayarlarınızdan Userkey'e gidin ve kendi tanımladığınız Parola ile birlikte kopyalayın.Bu değerleri daha sonra ve
SMSAccountPassworddeğişkenlerindeSMSAccountIdentificationdepolayacağız.SenderID / Kaynak Belirtme
Twilio:
Numaralar sekmesinden Twilio telefon numaranızı kopyalayın.ASPSMS:
Başlatanların Kilidini Aç Menüsünde bir veya daha fazla Kaynakçının kilidini açın veya alfasayısal bir Kaynak (Tüm ağlar tarafından desteklenmez) seçin.Daha sonra bu değeri değişkeninde
SMSAccountFromdepolayacağız.SMS sağlayıcısı kimlik bilgilerini uygulamaya aktarma
Kimlik bilgilerini ve gönderen telefon numarasını uygulamanın kullanımına açın:
public static class Keys { public static string SMSAccountIdentification = "My Idenfitication"; public static string SMSAccountPassword = "My Password"; public static string SMSAccountFrom = "+15555551234"; }Uyarı
Güvenlik - Hassas verileri hiçbir zaman kaynak kodunuzda depolamayın. Hesap ve kimlik bilgileri, örneği basit tutmak için yukarıdaki koda eklenir. Bkz. Jon Atten'in ASP.NET MVC: Özel Ayarları Kaynak Denetiminin Dışında Tut.
SMS sağlayıcısına veri aktarımının uygulanması
sınıfını
SmsServiceApp_Start\IdentityConfig.cs dosyasında yapılandırın.Kullanılan SMS sağlayıcısına bağlı olarak Twilio veya ASPSMS bölümünü etkinleştirin:
public class SmsService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Twilio Begin // var Twilio = new TwilioRestClient( // Keys.SMSAccountIdentification, // Keys.SMSAccountPassword); // var result = Twilio.SendMessage( // Keys.SMSAccountFrom, // message.Destination, message.Body // ); // Status is one of Queued, Sending, Sent, Failed or null if the number is not valid // Trace.TraceInformation(result.Status); // Twilio doesn't currently have an async API, so return success. // return Task.FromResult(0); // Twilio End // ASPSMS Begin // var soapSms = new WebApplication1.ASPSMSX2.ASPSMSX2SoapClient("ASPSMSX2Soap"); // soapSms.SendSimpleTextSMS( // Keys.SMSAccountIdentification, // Keys.SMSAccountPassword, // message.Destination, // Keys.SMSAccountFrom, // message.Body); // soapSms.Close(); // return Task.FromResult(0); // ASPSMS End } }Uygulamayı çalıştırın ve daha önce kaydettiğiniz hesapla oturum açın.
Denetleyicide eylem yöntemini etkinleştiren
IndexKullanıcı KimliğinizeManagetıklayın.
Ekle’ye tıklayın.
Birkaç saniye içinde doğrulama kodunu içeren bir kısa mesaj alırsınız. Girin ve Gönder'e basın.
Yönet görünümü, telefon numaranızın eklendiğini gösterir.
Kodu inceleme
// GET: /Account/Index
public async Task<ActionResult> Index(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.SetTwoFactorSuccess ? "Your two factor provider has been set."
: message == ManageMessageId.Error ? "An error has occurred."
: message == ManageMessageId.AddPhoneSuccess ? "The phone number was added."
: message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
: "";
var model = new IndexViewModel
{
HasPassword = HasPassword(),
PhoneNumber = await UserManager.GetPhoneNumberAsync(User.Identity.GetUserId()),
TwoFactor = await UserManager.GetTwoFactorEnabledAsync(User.Identity.GetUserId()),
Logins = await UserManager.GetLoginsAsync(User.Identity.GetUserId()),
BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(User.Identity.GetUserId())
};
return View(model);
}
Index Denetleyicideki Manage eylem yöntemi, durum iletisini önceki eyleminize göre ayarlar ve yerel parolanızı değiştirmek veya yerel hesap eklemek için bağlantılar sağlar.
Index Yöntemi ayrıca bu tarayıcı için durumunuzu veya 2FA telefon numaranızı, harici oturum açma bilgilerinizi, 2FA'yı etkinleştirmiş ve 2FA yöntemini anımsayın (daha sonra açıklanmıştır) görüntüler. Başlık çubuğunda kullanıcı kimliğinize (e-posta) tıklanması ileti iletmez.
Telefon Numarası : bağlantı geçişlerini Message=RemovePhoneSuccess sorgu dizesi olarak kaldır'a tıklayın.
https://localhost:44300/Manage?Message=RemovePhoneSuccess
[
]
Eylem yöntemi, AddPhoneNumber SMS mesajları alabilen bir telefon numarası girmek için bir iletişim kutusu görüntüler.
// GET: /Account/AddPhoneNumber
public ActionResult AddPhoneNumber()
{
return View();
}
Doğrulama kodunu gönder düğmesine tıklanması, telefon numarasını HTTP POST AddPhoneNumber eylem yöntemine gönderir.
// POST: /Account/AddPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Generate the token
var code = await UserManager.GenerateChangePhoneNumberTokenAsync(
User.Identity.GetUserId(), model.Number);
if (UserManager.SmsService != null)
{
var message = new IdentityMessage
{
Destination = model.Number,
Body = "Your security code is: " + code
};
// Send token
await UserManager.SmsService.SendAsync(message);
}
return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number });
}
yöntemi, GenerateChangePhoneNumberTokenAsync SMS iletisinde ayarlanacak güvenlik belirtecini oluşturur. SMS hizmeti yapılandırıldıysa, belirteç "Güvenlik kodunuz belirteçtir<>" dizesi olarak gönderilir.
SmsService.SendAsync yöntemi zaman uyumsuz olarak çağrılır, ardından uygulama doğrulama kodunu girebileceğiniz eylem yöntemine VerifyPhoneNumber (aşağıdaki iletişim kutusunu görüntüler) yönlendirilir.
Kodu girip gönder'e tıkladıktan sonra kod HTTP POST VerifyPhoneNumber eylem yöntemine gönderilir.
// POST: /Account/VerifyPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await UserManager.ChangePhoneNumberAsync(User.Identity.GetUserId(), model.PhoneNumber, model.Code);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInAsync(user, isPersistent: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess });
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "Failed to verify phone");
return View(model);
}
yöntemi, ChangePhoneNumberAsync gönderilen güvenlik kodunu denetler. Kod doğruysa, telefon numarası tablonun alanına AspNetUsers eklenirPhoneNumber. Bu çağrı başarılı SignInAsync olursa yöntemi çağrılır:
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
// Clear the temporary cookies used for external and two factor sign ins
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie,
DefaultAuthenticationTypes.TwoFactorCookie);
AuthenticationManager.SignIn(new AuthenticationProperties
{
IsPersistent = isPersistent
},
await user.GenerateUserIdentityAsync(UserManager));
}
parametresi, isPersistent kimlik doğrulama oturumunun birden çok istekte kalıcı olup olmadığını ayarlar.
Güvenlik profilinizi değiştirdiğinizde yeni bir güvenlik damgası oluşturulur ve AspNetUsers tablosunun alanında depolanırSecurityStamp.
SecurityStamp Alanın güvenlik tanımlama bilgisinden farklı olduğunu unutmayın. Güvenlik tanımlama bilgisi tabloda (veya Kimlik Veritabanı'nda AspNetUsers başka bir yerde) depolanmaz. Güvenlik tanımlama bilgisi belirteci DPAPI kullanılarak otomatik olarak imzalanır ve ve süre sonu bilgileriyle UserId, SecurityStamp oluşturulur.
Tanımlama bilgisi ara yazılımı her istekte tanımlama bilgisini denetler.
SecurityStampValidator sınıfındaki Startup yöntemi db'ye isabet eder ve ile belirtildiği gibi güvenlik damgasını validateIntervaldüzenli aralıklarla denetler. Güvenlik profilinizi değiştirmediğiniz sürece bu yalnızca 30 dakikada bir (örneğimizde) gerçekleşir. Veritabanına yapılan yolculukları en aza indirmek için 30 dakikalık aralık seçildi.
Güvenlik profilinde SignInAsync herhangi bir değişiklik yapıldığında yönteminin çağrılması gerekir. Güvenlik profili değiştiğinde veritabanı alanı güncelleştirir SecurityStamp ve yöntemini çağırmadan SignInAsyncyalnızca OWIN işlem hattının veritabanına bir sonraki isabetinde ( validateIntervalthe ) kadar oturumunuz açık kalır. Yöntemini hemen döndürülecek şekilde değiştirerek SignInAsync ve tanımlama bilgisi validateInterval özelliğini 30 dakikadan 5 saniyeye ayarlayarak bunu test edebilirsiniz:
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
return;
// Clear any partial cookies from external or two factor partial sign ins
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie,
DefaultAuthenticationTypes.TwoFactorCookie);
AuthenticationManager.SignIn(new AuthenticationProperties
{
IsPersistent = isPersistent
},
await user.GenerateUserIdentityAsync(UserManager));
}
public void ConfigureAuth(IAppBuilder app) {
// Configure the db context, user manager and role manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a
// third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider {
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add
// an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
//validateInterval: TimeSpan.FromMinutes(30),
validateInterval: TimeSpan.FromSeconds(5),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
Yukarıdaki kod değişiklikleriyle, güvenlik profilinizi değiştirebilirsiniz (örneğin, İki Faktör Etkin durumunu değiştirerek) ve yöntem başarısız olduğunda SecurityStampValidator.OnValidateIdentity 5 saniye içinde oturumunuz kapatılır. yöntemindeki SignInAsync dönüş satırını kaldırın, başka bir güvenlik profili değişikliği yapın ve oturumunuz kapatılmaz. SignInAsync yöntemi yeni bir güvenlik tanımlama bilgisi oluşturur.
İki öğeli kimlik doğrulamayı etkinleştirme
Örnek uygulamada, iki öğeli kimlik doğrulamasını (2FA) etkinleştirmek için kullanıcı arabirimini kullanmanız gerekir. 2FA'yı etkinleştirmek için gezinti çubuğunda kullanıcı kimliğinize (e-posta diğer adı) tıklayın. 
2FA'yı etkinleştir'e tıklayın.
Oturumu kapatın, sonra yeniden oturum açın. E-postayı etkinleştirdiyseniz ( önceki öğreticime bakın), 2FA için SMS veya e-postayı seçebilirsiniz.
Kodu girebileceğiniz Kodu Doğrula sayfası görüntülenir (SMS veya e-postadan).
Bu tarayıcıyı anımsa onay kutusuna tıkladığınızda, bu bilgisayar ve tarayıcıyla oturum açmak için 2FA kullanmanız gerekmeyecektir. 2FA'yı etkinleştirmek ve Bu tarayıcıyı anımsa seçeneğine tıklamak, bilgisayarınıza erişimi olmadığı sürece hesabınıza erişmeye çalışan kötü amaçlı kullanıcılara karşı güçlü 2FA koruması sağlar. Bunu düzenli olarak kullandığınız herhangi bir özel makinede yapabilirsiniz.
Bu tarayıcıyı anımsa'yı ayarlayarak, düzenli olarak kullanmadığınız bilgisayarlardan 2FA'nın ek güvenliğini elde edersiniz ve kendi bilgisayarlarınızda 2FA'dan geçmek zorunda kalmadan kolaylık elde edersiniz.
İki öğeli kimlik doğrulama sağlayıcısını kaydetme
Yeni bir MVC projesi oluşturduğunuzda , IdentityConfig.cs dosyası bir İki öğeli kimlik doğrulama sağlayıcısını kaydetmek için aşağıdaki kodu içerir:
public static ApplicationUserManager Create(
IdentityFactoryOptions<ApplicationUserManager> options,
IOwinContext context)
{
var manager = new ApplicationUserManager(
new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Register two factor authentication providers. This application uses Phone and Emails as a
// step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is: {0}"
});
manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is: {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>
(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
2FA için telefon numarası ekleme
Denetleyicideki AddPhoneNumberManage eylem yöntemi bir güvenlik belirteci oluşturur ve bunu sağladığınız telefon numarasına gönderir.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Generate the token and send it
var code = await UserManager.GenerateChangePhoneNumberTokenAsync(
User.Identity.GetUserId(), model.Number);
if (UserManager.SmsService != null)
{
var message = new IdentityMessage
{
Destination = model.Number,
Body = "Your security code is: " + code
};
await UserManager.SmsService.SendAsync(message);
}
return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number });
}
Belirteci gönderdikten sonra eylem yöntemine VerifyPhoneNumber yönlendirilir ve burada 2FA için SMS kaydetmek için kodu girebilirsiniz. Telefon numarasını doğrulayana kadar SMS 2FA kullanılmaz.
2FA'yi etkinleştirme
Eylem EnableTFA yöntemi 2FA'yi etkinleştirir:
// POST: /Manage/EnableTFA
[HttpPost]
public async Task<ActionResult> EnableTFA()
{
await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true);
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInAsync(user, isPersistent: false);
}
return RedirectToAction("Index", "Manage");
}
2FA'yı SignInAsync etkinleştirme güvenlik profilinde yapılan bir değişiklik olduğundan çağrılmalıdır. 2FA etkinleştirildiğinde, kullanıcının kaydettiği 2FA yaklaşımlarını (örnekte SMS ve e-posta) kullanarak oturum açmak için 2FA kullanması gerekir.
QR kod oluşturucuları gibi daha fazla 2FA sağlayıcısı ekleyebilir veya kendi sağlayıcınızı yazabilirsiniz.
Not
2FA kodları Zamana Dayalı Tek Seferlik Parola Algoritması kullanılarak oluşturulur ve kodlar altı dakika boyunca geçerlidir. Kodu girmeniz altı dakikadan uzun sürerse Geçersiz kod hata iletisi alırsınız.
Sosyal ve yerel oturum açma hesaplarını birleştirme
E-posta bağlantınıza tıklayarak yerel ve sosyal hesapları birleştirebilirsiniz. Aşağıdaki "RickAndMSFT@gmail.com" dizisinde ilk olarak yerel oturum açma olarak oluşturulur, ancak hesabı önce sosyal oturum açma günlüğü olarak oluşturabilir, ardından yerel oturum açma bilgisi ekleyebilirsiniz.
Yönet bağlantısına tıklayın. Bu hesapla ilişkili 0 harici (sosyal oturum açma) not edin.
Başka bir oturum açma hizmetinin bağlantısına tıklayın ve uygulama isteklerini kabul edin. İki hesap birleştirildi, her iki hesapla da oturum açabileceksiniz. Kimlik doğrulama hizmetindeki sosyal günlüklerinin kapalı olması veya daha çok sosyal hesaplarına erişimin kaybedilmiş olması durumunda kullanıcılarınızın yerel hesaplar eklemesini isteyebilirsiniz.
Aşağıdaki görüntüde, Tom bir sosyal oturum açma işlemidir ( Dış Oturum Açma bilgileri: 1 sayfada gösterilmiştir).
Parola seç'e tıklanması, aynı hesapla ilişkili yerel bir oturum açma eklemenize olanak tanır.
Deneme yanılma saldırılarından hesap kilitlenmesi
Kullanıcı kilitlemeyi etkinleştirerek uygulamanızdaki hesapları sözlük saldırılarına karşı koruyabilirsiniz. yönteminde ApplicationUserManager Create aşağıdaki kod kilitlemeyi yapılandırıyor:
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
Yukarıdaki kod yalnızca iki faktörlü kimlik doğrulaması için kilitlemeyi etkinleştirir. Hesap denetleyicisinin yönteminde Login true olarak değiştirerek shouldLockout oturum açma işlemleri için kilitlemeyi etkinleştirebilirsiniz ancak hesabı DOS oturum açma saldırılarına açık hale getirdiğinden oturum açma işlemleri için kilitlemeyi etkinleştirmemenizi öneririz. Örnek kodda, yönteminde ApplicationDbInitializer Seed oluşturulan yönetici hesabı için kilitleme devre dışı bırakılır:
public static void InitializeIdentityForEF(ApplicationDbContext db)
{
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
const string name = "admin@example.com";
const string roleName = "Admin";
//Create Role Admin if it does not exist
var role = roleManager.FindByName(roleName);
if (role == null)
{
role = new IdentityRole(roleName);
var roleresult = roleManager.Create(role);
}
var user = userManager.FindByName(name);
if (user == null)
{
user = new ApplicationUser { UserName = name, Email = name };
var result = userManager.Create(user, GetSecurePassword());
result = userManager.SetLockoutEnabled(user.Id, false);
}
// Add user admin to Role Admin if not already added
var rolesForUser = userManager.GetRoles(user.Id);
if (!rolesForUser.Contains(role.Name))
{
var result = userManager.AddToRole(user.Id, role.Name);
}
}
Kullanıcının doğrulanmış bir e-posta hesabına sahip olmasını gerektirme
Aşağıdaki kod, kullanıcının oturum açabilmesi için doğrulanmış bir e-posta hesabına sahip olmasını gerektirir:
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Require the user to have a confirmed email before they can log on.
var user = await UserManager.FindByNameAsync(model.Email);
if (user != null)
{
if (!await UserManager.IsEmailConfirmedAsync(user.Id))
{
ViewBag.errorMessage = "You must have a confirmed email to log on.";
return View("Error");
}
}
// This doen't count login failures towards lockout only two factor authentication
// To enable password failures to trigger lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password,
model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
SignInManager 2FA gereksinimini nasıl denetler?
2FA'nın etkinleştirilip etkinleştirilmediğini görmek için hem yerel oturum açma hem de sosyal oturum açma denetimi. 2FA etkinleştirilirse, SignInManager oturum açma yöntemi döndürür SignInStatus.RequiresVerificationve kullanıcı eylem yöntemine SendCode yönlendirilir ve burada günlüğü sırayla tamamlamak için kodu girmesi gerekir. Kullanıcının yerel kullanıcı tanımlama bilgisinde RememberMe ayarlanmışsa, SignInManager işlevi döndürülecek SignInStatus.Success ve 2FA üzerinden geçmesi gerekmeyecektir.
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Require the user to have a confirmed email before they can log on.
var user = await UserManager.FindByNameAsync(model.Email);
if (user != null)
{
if (!await UserManager.IsEmailConfirmedAsync(user.Id))
{
ViewBag.errorMessage = "You must have a confirmed email to log on.";
return View("Error");
}
}
// This doen't count login failures towards lockout only two factor authentication
// To enable password failures to trigger lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password,
model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
// Sign in the user with this external login provider if the user already has a login
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl });
case SignInStatus.Failure:
default:
// If the user does not have an account, then prompt the user to create an account
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
}
}
Aşağıdaki kod eylem SendCode yöntemini gösterir. Kullanıcı için etkinleştirilmiş tüm 2FA yöntemleriyle bir SelectListItem oluşturulur.
SelectListItem, kullanıcının 2FA yaklaşımını (genellikle e-posta ve SMS) seçmesini sağlayan DropDownListFor yardımcısına geçirilir.
public async Task<ActionResult> SendCode(string returnUrl)
{
var userId = await SignInManager.GetVerifiedUserIdAsync();
if (userId == null)
{
return View("Error");
}
var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(userId);
var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl });
}
Kullanıcı 2FA yaklaşımını HTTP POST SendCode gönderdikten sonra eylem yöntemi çağrılır, SignInManager 2FA kodunu gönderir ve kullanıcı, oturum açma işlemini tamamlamak için VerifyCode kodu girebileceği eylem yöntemine yönlendirilir.
//
// POST: /Account/SendCode
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SendCode(SendCodeViewModel model)
{
if (!ModelState.IsValid)
{
return View();
}
// Generate the token and send it
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
{
return View("Error");
}
return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl });
}
2FA Kilitleme
Oturum açma parolası denemesi hatalarında hesap kilitleme ayarlayabilirsiniz, ancak bu yaklaşım oturum açma bilgilerinizi DOS kilitlemelerine duyarlı hale getirir. Hesap kilitlemeyi yalnızca 2FA ile kullanmanızı öneririz.
ApplicationUserManager oluşturulduğunda, örnek kod 2FA kilitlemesini ve MaxFailedAccessAttemptsBeforeLockout beş olarak ayarlar. Bir kullanıcı oturum açtığında (yerel hesap veya sosyal hesap aracılığıyla), 2FA'daki başarısız girişimlerin her biri depolanır ve maksimum denemeye ulaşılırsa, kullanıcı beş dakika boyunca kilitlenir (kilitleme süresini ile DefaultAccountLockoutTimeSpanayarlayabilirsiniz).
Ek Kaynaklar
- kimlik önerilen kaynakları ASP.NET Kimlik bloglarının, videolarının, öğreticilerinin ve harika SO bağlantılarının tam listesi.
- Facebook, Twitter, LinkedIn ve Google OAuth2 ile MVC 5 Uygulaması Oturum açma , kullanıcılar tablosuna profil bilgilerinin nasıl ekleneceğini de gösterir.
- ASP.NET MVC and Identity 2.0: Understanding the Basics by John Atten.
- ASP.NET Kimliği ile Hesap Onayı ve Parola Kurtarma
- ASP.NET Identity’ye Giriş
- Pranav Rastogi tarafından ASP.NET Identity 2.0.0 RTM duyurus.
- ASP.NET Identity 2.0: John Atten tarafından Hesap Doğrulama ve Two-Factor Yetkilendirmesi Ayarlama .