5

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);
    }
mohsen
  • 1,763
  • 3
  • 17
  • 55
Samantha J T Star
  • 30,952
  • 84
  • 245
  • 427
  • This might point you to the right direction. http://stackoverflow.com/questions/19505526/asp-net-owin-identity-how-to-get-userid-from-a-web-api-controller – Spock Oct 26 '13 at 11:40

3 Answers3

16

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");
        }
Hootan
  • 196
  • 1
  • 6
  • Nice! but You should consider using Depency Injection inside your controller. There you'll need to inject `UserManager` only. without Store etc. – Bellash Aug 28 '21 at 11:18
10

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);
Brendan Green
  • 11,676
  • 5
  • 44
  • 76
  • 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 Apr 10 '14 at 15:07
  • 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. – jporcenaluk Apr 10 '14 at 15:12
  • 7
    Efficiency has nothing to do with it. You are providing a mechanism for an attacker to determine that a username exists in your website. – Brendan Green Apr 10 '14 at 23:51
  • 1
    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. – jporcenaluk Apr 11 '14 at 01:32
  • 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. – Gang Gao Feb 03 '16 at 14:56
  • @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: http://troyhunt.com – Brendan Green Feb 04 '16 at 04:35
  • @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. – Gang Gao Feb 05 '16 at 11:05
  • 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. – perustaja Jan 01 '21 at 16:56
0

I believe this post is a duplicate of How can I make my MVC5 ASP.NET Identity login action check if a user name exists?

One way to solve this is to do look up in your database to see if user exists - something like -> if(myUserRepository.GetUserByUserName(model.UserName) != null) *User exists*

There should also be a UserManager.FindByName(model.UserName) method which would do the same thing

But more importantly, are you sure you want to do this? If you give an error message specifying that the username is wrong you give hackers an opportunity to find valid usernames. They can then run scripts that try all usernames on your site and get a list of valid usernames.

Community
  • 1
  • 1
Zaphod
  • 1,412
  • 2
  • 13
  • 27