MVC使用ASP.NET Identity 2.0實現用戶身份安全相關功能,比如通過短信或郵件發送安全碼,賬戶鎖定等


本文體驗在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方法包含了驗證用戶名和密碼以及發送安全碼的邏輯:

1
2

 

PhoneNumberTokenProvider和EmailTokenProvider都繼承於EmailTokenProvider,這個基類負責向用戶發送短信或email。發送的前提是需要注冊EmailService和SmsService,如下:

4

 

□ Account Lockout鎖住帳號

當用戶輸錯密碼超過規定的次數,帳號就會被鎖住。

 

在ApplicationUserManager中的Create方法也包含了鎖住帳號的邏輯:

3

 

→在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鏈接:

5

 

填寫注冊信息,點擊注冊:

6

 

注意:在Web.config中配置的mailDrop文件夾,需要創建,否則報錯!

 

找到mailDrop文件夾,使用Foxmail打開后綴為eml的文件,看到:

8

 

點擊鏈接地址:

9

 

點擊"Click here to Log in"並登錄:

10

 

→運行項目 測試賬戶鎖定

修改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次錯誤密碼,出現提示帳號被鎖住的界面:

11

當然還有一些其它功能,比如密碼重置等。

 

參考資料:
Developing Secure ASP.NET MVC Applications using ASP.NET Identity 2.0

github項目地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM