How can I check if a user exists in my Login action?

28,906

Solution 1

i did it so:

        var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

        if (UserManager.FindByName("Admin") == null)
        {
            var user = new ApplicationUser() { UserName = "Admin" };
            UserManager.Create(user, "Admin123");
            UserManager.AddToRole(user.Id, "Admin");
        }

Solution 2

This is a bad idea

If you are going to validate the username, and report that the username does not exist, you allow potential hackers to easily determine usernames that are registered via the website.

The actual error message that is returned to the user is (ASPNET.Identity v1):

Invalid username or password

Otherwise, as detailed, you can check for the existence of a user with the given username via:

var user = await UserManager.FindByNameAsync(username);
Share:
28,906
Samantha J T Star
Author by

Samantha J T Star

I'm in the Philippines so if you send some comment I may not be able to answer if I am sleeping :-) The good thing is I work all day until late each night.

Updated on August 14, 2020

Comments

  • Samantha J T Star
    Samantha J T Star over 3 years

    I am starting to use the new identity management and have a simple need. When my user logs in with a wrong name it reports a password error. How can I change this so that it also checks to see if the username exists using the dbcontext method ?

        public ActionResult Login(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                // Validate the password
                IdentityResult result = IdentityManager.Authentication.CheckPasswordAndSignIn(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
                if (result.Success)
                {
                    return Redirect("~/home");
                }
                else
                {
                    AddErrors(result);
                }
            }
    
            // If we got this far, something failed, redisplay form
            return View(model);
        }
    
  • jporcenaluk
    jporcenaluk about 10 years
    I guess…but that sounds really inefficient. If you had to run through a list of all possible usernames, even within reason (let’s say limiting it to 8 maximum letter combinations), you’d be hitting the server 208,827,064,576 times (26^8). If it takes a second for the round trip to the server and back, it would take 6,621 years to go through all of the possibilities. Of course, I’m sure the you could send and receive requests asynchronously, but I think you may notice the server getting DDOS’d first. And at the end, you'd have a list of usernames. Thoughts?
  • jporcenaluk
    jporcenaluk about 10 years
    If your site is Facebook-sized and you can handle millions of extra requests a day without you noticing, then I would be more concerned.
  • Brendan Green
    Brendan Green about 10 years
    Efficiency has nothing to do with it. You are providing a mechanism for an attacker to determine that a username exists in your website.
  • jporcenaluk
    jporcenaluk about 10 years
    I agree that it is less secure, and maybe I was arguing the wrong point about the efficiency of an attacker. Even being less secure, this code has legitimate purposes. Perhaps the question we should be asking is "What is your application doing? How secure do you need it to be?" For example, Reddit and stackoverflow already have all of their usernames public. I can assume this code would be fine for a Reddit clone. But a bank? For a banking application, you raise a good point and no one should use it for that.
  • Gang Gao
    Gang Gao about 8 years
    To be honest I am not quite sure what sort of information a username can reveal to a hacker. I would think the security risk is quite small if the api controller which exposes method like UserExists (string username) is protected via proper security measure, e.g. Asp.Net identity.
  • Brendan Green
    Brendan Green about 8 years
    @gaog That a a user with a given username is registered with this website. Now if there has been a breach of some other website that also uses the same username, there is an increased likelihood that I now know the password for this user. Even if I didn't, let's say that the username is the email address. Contrast that with the recent Ashley Madison breach - just by attempting a logon with a username of someone that I know, I can now determine that they have an account with this particular website. Recommended reading: troyhunt.com
  • Gang Gao
    Gang Gao about 8 years
    @Brendan Green I agree if the username is a email address it should be protected as it is almost a personal identity nowaday. But I am not 100% convinced with your first use case. If user's credential in site A has been known to the hackers, they might just go ahead to try their luck in Site B with the same credential instead of asking if the username exists.
  • perustaja
    perustaja over 3 years
    I know I am really late here but allowing a user to see if a username exists is not a security concern in most cases. What's stopping them from attempting to signup under the email or username? It may not be as convenient but you are still exposing what names are taken.
  • Bellash
    Bellash over 2 years
    Nice! but You should consider using Depency Injection inside your controller. There you'll need to inject UserManager<ApplicationUser> only. without Store etc.