locked
Reset Password by Admin Role RRS feed

  • Question

  • User-351779185 posted

    I am building my first application with Asp.Net Core 3.1 MVC using Visual Studio 2019.

    As some users do not have an e-mail account, all users login with a UserName, which works fine. As some users do not have an e-mail account, I would like the Admin role to reset a users   password if they forget it.

    I have searched around the internet for example codes and to be honest I have confused myself.

    I have created the following code but get an 'squealy red line' for the 'HashPassword' in the Account Controller which i don't quite understand.

    Could someone please advise where I am going wrong how to fix it?

    View Model

    public class AdminResetPasswordViewModel
        {
            public string Id { get; set; }
    
            [Required]
            [DataType(DataType.Password)]
            [Display(Name = "New password")]
            public string NewPassword { get; set; }
    
            [DataType(DataType.Password)]
            [Display(Name = "Confirm new password")]
            [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
            public string ConfirmPassword { get; set; }
        }

    View

    <h2>Reset Password</h2>
    <hr />
    <div class="form-horizontal">
        <h4>ResetPasswordViewModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Id)
    
        <div class="form-group">
            @Html.LabelFor(model => model.NewPassword, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.NewPassword, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewPassword, "", new { @class = "text-danger" })
            </div>
        </div>
    
        <div class="form-group">
            @Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
            </div>
        </div>
    
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Reset Password" class="btn btn-default" />
            </div>
        </div>
    </div>
    @section Scripts {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    }

    Account Controller

    public class AccountController : Controller
        {
            private readonly UserManager<IdentityUser> userManager;
            private readonly SignInManager<IdentityUser> signInManager;
    
            public AccountController(UserManager<IdentityUser> userManager,
                                    SignInManager<IdentityUser> signInManager)
            {
                this.userManager = userManager;
                this.signInManager = signInManager;
            }
    
            //Register New User
            [HttpGet]
            public IActionResult Register()
            {
                return View();
            }
    
            [HttpPost]
            public async Task<IActionResult> Register(RegisterViewModel model)
            {
                {
                    if (ModelState.IsValid)
                    {
                        var user = new IdentityUser { UserName = model.Username, Email = model.Email };
                        var result = await userManager.CreateAsync(user, model.Password);
    
                        if (result.Succeeded)
                        {
                            if (signInManager.IsSignedIn(User) && User.IsInRole("Admin"))
                            {
                                return RedirectToAction("ListUsers", "Administration");
                            }
                            await signInManager.SignInAsync(user, isPersistent: false);
                            return RedirectToAction("Index", "Items");
                        }
    
                        foreach (var error in result.Errors)
                        {
                            ModelState.AddModelError("", error.Description);
                        }
                    }
                    return View();
                }
            }
    
            //Login
    
            [HttpGet]
            public IActionResult Login()
            {
                return View();
            }
    
            [HttpPost]
            public async Task<IActionResult> Login(LoginViewModel model, string returnUrl)
            {
                {
                    if (ModelState.IsValid)
                    {
                        var result = await signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, false);
    
                        if (result.Succeeded)
                        {
                            if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
                            {
                                return Redirect(returnUrl);
                            }
                            else
                            {
                                return RedirectToAction("Index", "Items");
                            }
                        }
    
                        ModelState.AddModelError(string.Empty, "Invalid Login Attempt");
                    }
                    return View();
                }
            }
    
            //Logout
            [HttpPost]
            public async Task<IActionResult> Logout()
            {
                await signInManager.SignOutAsync();
                return RedirectToAction("Login", "Account");
            }
    
            //Password Reset by Admin
            [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> AdminResetPassword(AdminResetPasswordViewModel model)
            {
                var user = await userManager.FindByIdAsync(model.Id);
                if (user == null)
                {
                    return NotFound();
                }
    
                user.PasswordHash = userManager.PasswordHasher.HashPassword(model.NewPassword);
                var result = await userManager.UpdateAsync(user);
    
                if (!result.Succeeded)
                {
                    return View("ListUsers", "Administration");
                }
    
                return View("ListUsers", "Administration");
            }
    
            [HttpGet]
            public IActionResult AccessDenied()
            {
                return View();
            }
        }
    }

    Friday, July 24, 2020 9:24 AM

Answers

  • User475983607 posted

    The HashPassword expects two parameters IdentityUser and a password string.  You pass only the password string.

    userManager.PasswordHasher.HashPassword(user, model.NewPassword);

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 24, 2020 12:16 PM

All replies

  • User665608656 posted

    Hi Mick3911,

    I have created the following code but get an 'squealy red line' for the 'HashPassword' in the Account Controller which i don't quite understand.

    For this issue, HashPassword() must needs namespace called  ‘Microsoft.AspNet.Identity’  and you can search and install it in NuGet in your project as follow:

    Then you just need to add  using Microsoft.AspNet.Identity; to your controller.

    Hope it can help you.

    Best Regards,

    YongQing.

    Friday, July 24, 2020 10:05 AM
  • User-351779185 posted

    Hi Yongqing Yu,

    I am already using Microsoft.AspNetCore.Identity for the userManager and the signinManager.

    Friday, July 24, 2020 10:12 AM
  • User-351779185 posted

    The error message I am getting is this;

    There is no argument given that corresponds to the required formal parameter 'password' of 'IPasswordHasher<IdentityUser>.HashPassword(IdentityUser, string)'

    which I am don't understand/I'm confused about.

    Friday, July 24, 2020 12:08 PM
  • User475983607 posted

    The HashPassword expects two parameters IdentityUser and a password string.  You pass only the password string.

    userManager.PasswordHasher.HashPassword(user, model.NewPassword);

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 24, 2020 12:16 PM
  • User-351779185 posted

    Hi mgebhard,

    That worked great.

    Many thanks for your help.

    Tuesday, July 28, 2020 4:24 PM