• 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项目地址

  • 相关阅读:
    webpack常用插件及作用
    函数柯里化
    防抖和节流
    实现深拷贝
    实现new操作符
    关于js中断ajax请求
    从输入 URL 到页面加载完成,发生了什么?
    vue路由传参params和query的区别
    input输入框限制(座机,手机号码)
    判断当前页面是不是用户正在浏览的页面
  • 原文地址:https://www.cnblogs.com/darrenji/p/3761690.html
Copyright © 2020-2023  润新知