How to make WebSecurity.Login to login using username or email?

30,912

Solution 1

You could inherit from the SimpleMembershipProvider and just override the ValidateUser method like this.

public class ExtendedSimpleMembershipProvider : SimpleMembershipProvider
{
    public override bool ValidateUser(string login, string password)
    {
        // check to see if the login passed is an email address
        if (IsValidEmail(login))
        {
            string actualUsername = base.GetUserNameByEmail(login);
            return base.ValidateUser(actualUsername, password);
        }
        else
        {
            return base.ValidateUser(login, password);
        }

    }

    bool IsValidEmail(string strIn)
    {
        // Return true if strIn is in valid e-mail format.
        return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
    }

}

This is just one approach. You could write your own MembershipProvider but if you only need to change the ValidateUser method this should work.

Add the following configuration to the web.config to setup the provider.

  <membership defaultProvider="ExtendedSimpleMembershipProvider">   
    <providers>
    <clear/>
    <add name="ExtendedSimpleMembershipProvider"
         type="MyProject.Web.SimpleMembershipProvider, MyProject.Web"/>
    </providers>
  </membership>

That should get you going in the right direction.

Solution 2

WebSecurity just calls FormsAuthentication under the hood. You can do this:

if (WebSecurity.UserExists(username)) 
{
     FormsAuthentication.SetAuthCookie(username, false);
}

Curious why you need this feature. (FYI: My reasoning for needing this is if a user has authenticated with PayPal in an Express Checkout (shopping cart) flow I allow them to be auto-logged into my site as that same user because I consider the risk very low that it would not be the right person).

May be of use: Difference between FormsAuthentication and WebSecurity

Solution 3

You can just pull the user with given email from UserProfiles table

 [HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
  var login = false;
  if (ModelState.IsValid)
  {
    if (!model.UserName.Contains("@"))
    {
      if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
        login = true;
    }
    else
    {
      var targetUser = db.UserProfiles.Where(u => u.Email == model.UserName).FirstOrDefault();
      if (targetUser != null && WebSecurity.Login(targetUser.UserName, model.Password, persistCookie: model.RememberMe))
        login = true;
    }

  }
  if (login)
    return Redirect(returnUrl);
  // If we got this far, something failed, redisplay form
  ModelState.AddModelError("", "The user name or password provided is incorrect.");
  return View(model);
}
Share:
30,912

Related videos on Youtube

Amr Elgarhy
Author by

Amr Elgarhy

Updated on July 09, 2022

Comments

  • Amr Elgarhy
    Amr Elgarhy almost 2 years

    WebSecurity.Login in simplemembership take username and password, how to make it to login the user using username or email instead of just username?, to make the user free to enter his email or username to login.

  • aruno
    aruno about 11 years
    I misunderstood the question and thought you meant without password - so that's what this is an answer for :)
  • rashleighp
    rashleighp almost 11 years
    I'd agree that its easy to guess but your average user is going to use it or something easy to guess anyway. Say you had David Jones. He might use , david.jones, jonesd, djones. But they are all ludicrously guessable so I don't think that it would make too much of a difference.