2

I'm trying to fix a bug in my application at the moment where the user email used for login is case sensitive when it should be case insensitive.

I am using the following code to do this in MVC:

public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var user = _userManager.Find(model.UserName, model.Password);

        if (user != null)
        {
            SignIn(user, model.RememberMe);
            return RedirectToAction("List", "Survey");
        }

        ModelState.AddModelError("LoginFailure", "Invalid username or password.");
    }

    return View(model);
}

_userManager is a UserManager, an override of the standard AspNet Identity UserManager. It seems as though this is using case sensitive comparisons.

I have looked into a number of ways of fixing this problem, including the obvious one of lower- or upper-casing all of the usernames as they are entered and changing the database to match, but I would rather fix this problem without having to edit the database if possible. I have already tried using lambda expressions but these do not seem to work for the Find method unfortunately.

My username column in the database has its collation as SQL_Latin1_General_CP1_CI_AS which I believe makes it case-insensitive for comparisons.

I have looked around for some time now and cannot find anybody complaining of exactly the same problem apart from the person in this link.

I would be very grateful for any help with this problem that does not involve DB manipulations, or even confirmation if that is the only way possible. Thank you.

Community
  • 1
  • 1
GallJ93
  • 603
  • 1
  • 5
  • 12

2 Answers2

0

Thanks to Sam Farajpour Ghamari's comments, I was able to find the override for the UserStore's findUserByName method and change this code:

public User GetByUsername(string username)
{
    return GetAll().FirstOrDefault(u => u.UserName == username);
}

to this:

public User GetByUsername(string username)
{
    return GetAll().FirstOrDefault(u => u.UserName.ToLower() == username.ToLower());
}

And it worked. Thanks for the help.

Sam FarajpourGhamari
  • 14,601
  • 4
  • 52
  • 56
GallJ93
  • 603
  • 1
  • 5
  • 12
0

Hi hope my code is helpful

Model

public class Users
{
        [Key]
        public int Id { get; set; }

        [Required]
        public string Username { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }
}

And this is my controller

public ActionResult Login(Users model)
{
    using (var db = new YourDBContext())
    {
        //check if database for username
        var accountCheck = db.Users.FirstOrDefault(u => u.Username == model.Username);

        if (model.Username != null && accountCheck != null)
        {
            var userPass = db.Users.Where(u => u.Username == model.Username).Select(u => u.Password);
            //Materializes the query into a readable list of array objects
            var materializePass = userPass.ToList();
            //Since query will only result to one , we ony have one array of result
            var password = materializePass[0];

            //Check username and password (Case Sensitive)
            if (accountCheck.Username == model.Username &&  model.Password == password )
            {
                //Your code here to redirect
            }
        }
    }
}
levinjay
  • 106
  • 1
  • 4