views:

278

answers:

3

Using ASP.NET forms authentication, how would you accept an e-mail address and password, use the e-mail address to lookup the username, then log them in with the looked up username and password?

We have this card system which has employee numbers, but no one can remember their numbers. The obvious would be use the e-mail addresses for the login, but the rest of the application depends on the username being the employee number.

Thanks. Code links / examples would be great.

Our current C# solution ends with a null reference exception on:

Response.Write(Membership.GetUser().UserName);

yet both of these work fine:

string userName = Membership.GetUserNameByEmail(emailAddress);
bool successfulLogin = Membership.ValidateUser(userName, password);

+3  A: 

Don't use the log in control. Just put your own text boxes there and perform your own authentication logic. If the user passes, call FormsAuthentication.RedirectFromLoginPage.

This will log them in without requiring them to enter their user name, as long as you can look it from their email.

See docs.

recursive
I have to say, this works. It is a great work around. I am just not sure why the default login control fails?
Dr. Zim
It may be because the Login control is trying to use the contents of the user text box as the user name.
recursive
Yep, I removed the login text field and it complains, so it must be doing that.
Dr. Zim
+6  A: 

Don't change the existing login control, just override the 'Authenticate' event to do your new custom logic. Also the FormsAuthentication.SetAuthCookie() function should help you override the username issues.

I haven't compiled this, but you should get the idea:

private void OnAuthenticate(object sender, AuthenticateEventArgs e)
{
    bool successfulLogin = false;
    string userName = Membership.GetUserNameByEmail(Login1.UserName); //the email address
    successfulLogin = Membership.ValidateUser(userName, Login1.Password);

    if(successfulLogin)
      FormsAuthentication.SetAuthCookie(userName, true);

    e.Authenticated = successfulLogin;
}
Brendan Kowitz
I don't know what I was thinking about. I re-read the question more carefully and this is a much better answer than mine.
womp
My only problem is that Membership.GetUser() is null afterward. Shouldn't I be able to do something like Response.Write( Membership.GetUser().UserName) ?
Dr. Zim
Is it null afterwards in the SAME request or subsequent requests? The "HttpContext.Current.User.Identity" property is populated by a built-in asp.net module so it won't be updated until the next request after authentication.
Brendan Kowitz
It is both null in the same and subsequent requests. However, the FormsAuthentication.RedirectFromLoginPage works in the subsequent page. I am not sure why the first works but the second fails:successfulLogin = Membership.ValidateUser(myName, Login1.Password);successfulLogin = FormsAuthentication.Authenticate(myName, Login1.Password);The second fails in both the Login form and the target page.
Dr. Zim
Not sure if this will help but, another thing I noticed was instead of doing "FormsAuthentication.SetAuthCookie(userName, true)", at this point in the process, if auth has succeeded you can sub in the desired username "Login1.UserName = userName;" and the normal login process will set the correct cookie for you.
Brendan Kowitz
Apparently Login1.UserName is read only. It really wants that Username, because it fails a build without it.
Dr. Zim
+1  A: 

I'm having the exact same problem. On subsequent page loads this works fine:

Response.Write(HttpContext.Current.User.Identity.Name);

But this tells me that the current user is null:

Response.Write(Membership.GetUser().UserName);
Joe