本文體驗在MVC中使用ASP.NET Identity 2.0,體驗與用戶身份安全有關的功能:
→install-package Microsoft.AspNet.Identity.Samples -Version 2.0.0-beta2 -Pre
安裝后,在App_Start,Controllers, Models, Views等處都添加了多個文件。在App_Start/IdentityConfig.cs中有6個類和一個枚舉:
● ApplicationUserManager:繼承於泛型基類UserManager<ApplicationUser>, ApplicationUser用來處理用戶的身份。
● ApplicationRoleManager
● EmailService
● SmsService
● ApplicationDbInitializer
● SignInHelper
● SignInStatus 枚舉
□ Two-Factor Authentication機制
在ASP.NET Identity 2.0中,使用了"Two-Factor Authentication機制"來保證用戶密碼的安全,當用戶密碼可能存在不安全隱患的時候,系統會以短信或郵件的方式向用戶發送安全碼。
在ApplicationUserManager中的Create方法包含了驗證用戶名和密碼以及發送安全碼的邏輯:
PhoneNumberTokenProvider和EmailTokenProvider都繼承於EmailTokenProvider,這個基類負責向用戶發送短信或email。發送的前提是需要注冊EmailService和SmsService,如下:
□ Account Lockout鎖住帳號
當用戶輸錯密碼超過規定的次數,帳號就會被鎖住。
在ApplicationUserManager中的Create方法也包含了鎖住帳號的邏輯:
→在EmailService中編寫發送右鍵的邏輯:
public class EmailService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Plug in your email service here to send an email. //配置 var mailMessage = new System.Net.Mail.MailMessage("qdjjx9441@sina.com", message.Destination, message.Subject, message.Body) //發送 SmtpClient client = new SmtpClient(); client.SendAsync(mailMessage, null); return Task.FromResult(0); } }
→在Web.config中的<configuration>節點下配置接收郵件的文件夾
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="F:\mailDrop"/>
</smtp>
</mailSettings>
</system.net>
→在Web.config中的<connectionStrings>節點配置連接字符串,用來把用戶信息保存到數據庫
<add name="DefaultConnection" connectionString=".;Initial Catalog=MVC_Identity-1-14;user id=sa;password=woshiniba;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
→AccontController中接收[HttpPost]的Register方法包含了用戶注冊后發送確認郵件的邏輯
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>"); ViewBag.Link = callbackUrl; return View("DisplayEmail"); } AddErrors(result); } // If we got this far, something failed, redisplay form return View(model); }
→運行項目 測試注冊、確認郵件、登錄
點擊右上方的Register鏈接:
填寫注冊信息,點擊注冊:
注意:在Web.config中配置的mailDrop文件夾,需要創建,否則報錯!
找到mailDrop文件夾,使用Foxmail打開后綴為eml的文件,看到:
點擊鏈接地址:
點擊"Click here to Log in"並登錄:
→運行項目 測試賬戶鎖定
修改App_Start/IdentityConfig.cs中, ApplicationUserManager類的相關部分為:
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(1);
manager.MaxFailedAccessAttemptsBeforeLockout = 2;
在App_Start/IdentityConfig.cs中,SignInHelper類的PasswordSignIn修改如下:
public async Task<SignInStatus> PasswordSignIn(string userName, string password, bool isPersistent, bool shouldLockout) { var user = await UserManager.FindByNameAsync(userName); //為測試帳號鎖住而添加 await UserManager.IsLockedOutAsync(user.Id); //如果用戶被鎖住,這里返true await UserManager.AccessFailedAsync(user.Id);//記錄登錄失敗的次數,如果登錄失敗次數大於或等於設定的次數,在設置鎖住時間內,用戶賬戶被鎖住 await UserManager.SetLockoutEnabledAsync(user.Id, true);//確認用戶賬戶被鎖住是否被啟用 if (user == null) { return SignInStatus.Failure; } if (await UserManager.IsLockedOutAsync(user.Id)) { return SignInStatus.LockedOut; } if (await UserManager.CheckPasswordAsync(user, password)) { return await SignInOrTwoFactor(user, isPersistent); } if (shouldLockout) { // If lockout is requested, increment access failed count which might lock out the user await UserManager.AccessFailedAsync(user.Id); if (await UserManager.IsLockedOutAsync(user.Id)) { return SignInStatus.LockedOut; } } return SignInStatus.Failure; }
再次登錄,試着輸入2次錯誤密碼,出現提示帳號被鎖住的界面:
當然還有一些其它功能,比如密碼重置等。
參考資料:
Developing Secure ASP.NET MVC Applications using ASP.NET Identity 2.0