c# - 允许用户使用电子邮件或用户名 (AspNet.Identity) 登录

标签 c# asp.net-mvc authentication asp.net-identity

我想知道这里是否有更高效的路线。使用 AspNet.Identity 我想允许用户使用他们的 UserNameEmail 登录到同一个文本框。我继续在 AccountController Login ActionResult 中解决了这个问题。我在调用之前运行检查:

var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: true);

支票:

//TODO: determine if there is a more efficient way to allow user to login either with Email || UserName
if (model.UserName.Contains("@"))
{
    using (var context = new ApplicationDbContext())
    {
        model.UserName = (context.Users.Any(p => p.Email == model.UserName)) ?
          context.Users.SingleOrDefault(p => p.Email == model.UserName).UserName :
          model.UserName;
    }
}

我的担忧有两方面:

  1. 他们是一种更有效的实用方法吗?
  2. 这样做是否会引入任何新的安全风险或性能风险?

I am including the entire ActionResult below for reference.

//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    //TODO: determine if there is a more efficient way to allow user to login either with Email || UserName
    if (model.UserName.Contains("@"))
    {
        using (var context = new ApplicationDbContext())
        {
            model.UserName = (context.Users.Any(p => p.Email == model.UserName)) ?
              context.Users.SingleOrDefault(p => p.Email == model.UserName).UserName :
              model.UserName;
        }
    }

    // This doesn't count login failures towards account lockout
    // To enable password failures to trigger account lockout, change to shouldLockout: true
    var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: true);
    switch (result)
    {
        case SignInStatus.Success:
            return RedirectToLocal(returnUrl);
        case SignInStatus.LockedOut:
            return View("Lockout");
        case SignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Invalid login attempt.");
            return View(model);
    }
}

related github issue #2 and #4

最佳答案

会有一个安全问题。如果你知道他的电子邮件,你可以得到另一个用户的用户名:

  1. 写下他的邮箱和错误的密码
  2. 然后系统加载相应的用户名,执行密码验证,失败并返回用户名被覆盖的模型

我会声明新变量而不是重用 model.UserName。如果您使用 FirstOrDefault,您的查询会更有效:

    var userName = model.UserName;
    using (var context = new ApplicationDbContext())
    {
       var user = context.Users.FirstOrDefault(p => p.Email == model.UserName);
       if (user != null)
       {
           userName = user.UserName;
       }
    }

var result = await SignInManager.PasswordSignInAsync(userName, model.Password, model.RememberMe, shouldLockout: true);

关于c# - 允许用户使用电子邮件或用户名 (AspNet.Identity) 登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26009221/

相关文章:

asp.net - 向 Asp.NET 中的选项预检请求添加 'access-control-allow-origin' 响应

reactjs - 如何使用 React 应用程序捕获 saml 身份验证中的 SAML 响应

c# - Redis ServiceStack - 轻松获取和设置一组值?

C# - 不应该的 CS0136

asp.net-mvc - 无需 ORM 即可查看 MVC 4 强类型数据

c# - Asp.Net MVC 形式, Controller 参数未知

c# - 如何使用 JavaScript 变量在 JavaScript 函数内获取 ASP.NET ClientID?

Java 与 C# GZip 压缩

java - 如何在 Spring 中以编程方式生成 session ID

php - 使用 Symfony 2.8 进行 LDAP 身份验证