Last active
October 28, 2021 14:45
-
-
Save luebster/ea50aefcad2b249b133e363c81c573b4 to your computer and use it in GitHub Desktop.
Easy way to manually reset a user's password in .net core identity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@page | |
@model Demo.Pages.Users.UpdateUserPasswordModel | |
@{ | |
} | |
<section class="section"> | |
<div class="container"> | |
<h1 class="is-headline">Update User Password</h1> | |
<form method="post"> | |
<div asp-validation-summary="All"> | |
<span>Please correct the following errors:</span> | |
</div> | |
<div class="field"> | |
<label class="label">Email</label> | |
<div class="control"> | |
<input class="input" asp-for="Input.Email" /> | |
</div> | |
</div> | |
<div class="field"> | |
<label class="label">New Password <span class="has-tooltip-multiline" data-tooltip="Password must be minimum 8 characters and contain at least 1 digit, 1 lowercase, 1 uppercase, and 1 non-alphanumeric (special character) "><i class="fas fa-info-circle"></i></span></label> | |
<div class="control"> | |
<input class="input" asp-for="Input.Password" /> | |
</div> | |
</div> | |
<div class="field"> | |
<label class="label">Confirm Password</label> | |
<div class="control"> | |
<input class="input" asp-for="Input.ConfirmPassword" /> | |
</div> | |
</div> | |
<div class="field"> | |
<div class="control"> | |
<button class="button is-green is-large">Submit</button> | |
</div> | |
</div> | |
</form> | |
</div> | |
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Demo.Models; | |
using Microsoft.AspNetCore.Authorization; | |
using Microsoft.AspNetCore.Identity; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.AspNetCore.Mvc.RazorPages; | |
using System; | |
using System.ComponentModel.DataAnnotations; | |
using System.Threading.Tasks; | |
namespace Demo.Pages.Users | |
{ | |
[Authorize(Roles = "Admin")] | |
public class UpdateUserPasswordModel : PageModel | |
{ | |
private readonly UserManager<AppUser> _userManager; | |
[BindProperty] | |
public InputModel Input { get; set; } | |
public UpdateUserPasswordModel(UserManager<AppUser> userManager) | |
{ | |
_userManager = userManager; | |
} | |
public void OnGet() | |
{ | |
} | |
public async Task<IActionResult> OnPostAsync() | |
{ | |
if (!ModelState.IsValid) | |
{ | |
return Page(); | |
} | |
var user = await _userManager.FindByNameAsync(Input.Email); | |
if (user == null) | |
{ | |
ModelState.AddModelError(string.Empty, "No user with that phone number exists."); | |
return Page(); | |
} | |
foreach (var validator in _userManager.PasswordValidators) | |
{ | |
var outcome = await validator.ValidateAsync(_userManager, null, Input.Password); | |
if (!outcome.Succeeded) | |
{ | |
foreach (var error in outcome.Errors) | |
{ | |
ModelState.AddModelError(string.Empty, error.Description); | |
} | |
} | |
} | |
if (!ModelState.IsValid) | |
{ | |
return Page(); | |
} | |
var result = await HardResetPasswordAsync(Input.Email, Input.Password); | |
if (result.Succeeded) | |
{ | |
user.LastPasswordChangedDate = DateTime.UtcNow; | |
await _userManager.UpdateAsync(user); | |
return Redirect("/Identity/Account/ResetPasswordConfirmation"); | |
} | |
foreach (var error in result.Errors) | |
{ | |
ModelState.AddModelError(string.Empty, error.Description); | |
} | |
return Page(); | |
} | |
#region password reset | |
public async Task<IdentityResult> HardResetPasswordAsync(string email, string newPassword) | |
{ | |
var user = await _userManager.FindByNameAsync(email); | |
return await ChangeUserPasswordAsync(user, newPassword); | |
} | |
private async Task<string> GeneratePasswordResetToken(AppUser user) | |
{ | |
return await _userManager.GeneratePasswordResetTokenAsync(user); | |
} | |
private async Task<IdentityResult> ChangeUserPasswordAsync(AppUser user, string newPassword) | |
{ | |
var token = await GeneratePasswordResetToken(user); | |
return await _userManager.ResetPasswordAsync(user, token, newPassword); | |
} | |
#endregion password reset | |
public class InputModel | |
{ | |
[Required] | |
[EmailAddress] | |
[Display(Name = "Email Address")] | |
public string Email { get; set; } | |
[Required] | |
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 8)] | |
//[DataType(DataType.Password)] | |
[Display(Name = "New Password")] | |
public string Password { get; set; } | |
//[DataType(DataType.Password)] | |
[Display(Name = "Confirm New Password")] | |
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] | |
public string ConfirmPassword { get; set; } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment