locked
Changing a password in ASPNET RRS feed

  • Question

  • User-861080172 posted

    Hey I've been trying to figure out how to change a simple password for two days now. I don't understand why it's so hard, the user registration was so automated in comparison.

    Basically, I just want to be able to input a new password while logged in. No fancy verifications, no emails, no tokens. I've tried the following:

     var userManager = new Microsoft.AspNet.Identity.UserManager<IdentityUser>(userStore);
    var user = userManager.Find(name.Getname, name.GetPass);
    
    userManager.ChangePassword(User.Identity.GetUserId(), name.GetPass, passBox.Text);

    But this does literally nothing. It doesn't throw an error but it doesn't change anything. I've also tried to manually change the password using a sql connection but I don't understand how the password hashes work. When I manually changed it and hashed it myself, it seemed to work. But when I logged in, it told me "invalid length for a Base-64 char array or string.'"

    Here is the code I used to hash it:

            public string HashPassword(string password)
            {
                byte[] salt;
                byte[] buffer2;
                if (password == null)
                {
                    throw new ArgumentNullException("password");
                }
                using (Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, 0x10, 0x3e8))
                {
                    salt = bytes.Salt;
                    buffer2 = bytes.GetBytes(0x20);
                }
                byte[] dst = new byte[0x31];
                System.Buffer.BlockCopy(salt, 0, dst, 1, 0x10);
                System.Buffer.BlockCopy(buffer2, 0, dst, 0x11, 0x20);
                return Convert.ToBase64String(dst);
            }

    If you can give me any help, I would seriously appreciate it. I really need help here.

    Friday, October 30, 2020 4:44 PM

Answers

  • User-939850651 posted

    Hi qiterpot,

    According to your description, I think you could try to add a TextBox for the user to enter a new password when logging in, and perform corresponding operations on it when logging in. For example, modify the user password when the login is successful.

    Of course you also need to verify the new password.

    Something like this:

    Login Page Code:

    @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                {
                    @Html.AntiForgeryToken()
                    <h4>Use a local account to log in.</h4>
                    <hr />
                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                    <div class="form-group">
                        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
                            @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @autocomplete = "off" })
                            @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
    <!-- change password input to TextBox for testing -->
                            @Html.TextBoxFor(m => m.Password, new { @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.Label("new Password", new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
                            <input type="text" id="newPass"  name="NewPassText" class="form-control" />
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <div class="checkbox">
                                @Html.CheckBoxFor(m => m.RememberMe)
                                @Html.LabelFor(m => m.RememberMe)
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <input type="submit" value="Log in" class="btn btn-default" />
                        </div>
                    </div>
                    <p>
                        @Html.ActionLink("Register as a new user", "Register")
                    </p>
                    @* Enable this once you have account confirmation enabled for password reset functionality
                <p>
                    @Html.ActionLink("Forgot your password?", "ForgotPassword")
                </p>*@
                }

    Controller Action:
    [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl, string NewPassText) { if (!ModelState.IsValid) { return View(model); } // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, change to shouldLockout: true var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true); switch (result) { case SignInStatus.Success: var LoginUser = UserManager.Find(model.Email, model.Password); if (LoginUser != null && !string.IsNullOrEmpty(NewPassText)) { UserManager.ChangePassword(LoginUser.Id, model.Password, NewPassText); } return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: return View(model); default: ModelState.AddModelError("", "Invalid login attempt."); return View(model); } }

    Result:

    If I misunderstood something, please let me know.

    Best regards,

    Xudong Peng

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 2, 2020 7:43 AM

All replies

  • User-1369959483 posted

    Hey, 

    Know more about this issue at https://idn-kxchange.com/remote-support

    Friday, October 30, 2020 4:56 PM
  • User-939850651 posted

    Hi qiterpot,

    According to your description, I think you could try to add a TextBox for the user to enter a new password when logging in, and perform corresponding operations on it when logging in. For example, modify the user password when the login is successful.

    Of course you also need to verify the new password.

    Something like this:

    Login Page Code:

    @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                {
                    @Html.AntiForgeryToken()
                    <h4>Use a local account to log in.</h4>
                    <hr />
                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                    <div class="form-group">
                        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
                            @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @autocomplete = "off" })
                            @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
    <!-- change password input to TextBox for testing -->
                            @Html.TextBoxFor(m => m.Password, new { @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.Label("new Password", new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
                            <input type="text" id="newPass"  name="NewPassText" class="form-control" />
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <div class="checkbox">
                                @Html.CheckBoxFor(m => m.RememberMe)
                                @Html.LabelFor(m => m.RememberMe)
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <input type="submit" value="Log in" class="btn btn-default" />
                        </div>
                    </div>
                    <p>
                        @Html.ActionLink("Register as a new user", "Register")
                    </p>
                    @* Enable this once you have account confirmation enabled for password reset functionality
                <p>
                    @Html.ActionLink("Forgot your password?", "ForgotPassword")
                </p>*@
                }

    Controller Action:
    [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl, string NewPassText) { if (!ModelState.IsValid) { return View(model); } // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, change to shouldLockout: true var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true); switch (result) { case SignInStatus.Success: var LoginUser = UserManager.Find(model.Email, model.Password); if (LoginUser != null && !string.IsNullOrEmpty(NewPassText)) { UserManager.ChangePassword(LoginUser.Id, model.Password, NewPassText); } return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: return View(model); default: ModelState.AddModelError("", "Invalid login attempt."); return View(model); } }

    Result:

    If I misunderstood something, please let me know.

    Best regards,

    Xudong Peng

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 2, 2020 7:43 AM