aspnet / Identity

[Archived] ASP.NET Core Identity is the membership system for building ASP.NET Core web applications, including membership, login, and user data. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
1.96k stars 869 forks source link

Template code supplies email for PasswordSignIn function which requires username #1920

Closed ortund closed 6 years ago

ortund commented 6 years ago

This has always been a problem I've had implementing logins with Identity.

So the PasswordSignIn function requires the userName be supplied:

public static SignInStatus PasswordSignIn<TUser, TKey>(this SignInManager<TUser, TKey> manager, string userName, string password, bool isPersistent, bool shouldLockout)
    where TUser : class, IUser<TKey>
    where TKey : IEquatable<TKey>;

Whether on an MVC project or an ASP.NET Web Forms project, the project template, when using Individual Accounts, generates code that supplies the email address:

protected void LogIn(object sender, EventArgs e)
{
    if (IsValid)
    {
        // Validate the user password
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger lockout, change to shouldLockout: true
        var result = signinManager.PasswordSignIn(Email.Text, Password.Text, RememberMe.Checked, shouldLockout: false);

Because of this, the login will always fail. In order to rectify, it's necessary to either require the user to remember their username (I never remember username, but always remember email address), or to modify the code as follows to get the username associated with the account associated with the input email address:

{
    if (IsValid)
    {
        // Validate the user password
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

        var user = manager.FindByEmail(Email.Text);
        if (user != null)
        {
            var result = signinManager.PasswordSignIn(user.UserName, Password.Text, RememberMe.Checked, shouldLockout: false);

Seems a little bit counter intuitive to have a template written that I have to modify so that it actually works.

blowdart commented 6 years ago

So yes, templates to simplify make email and username the same, and if you let folks edit you have to keep it in sync. Your avatar is quite appropriate here. So, dupe of #1541 and partially #801

Which will be addressed by #1721 eventually.

As it's a dupe, and a tracking issue is there for work to fix it, I'm going to close this one, but feel free to reopen if you don't believe the other issue covers the same thing.