ASP.NET пароль сброса идентичности
Как я могу получить пароль пользователя в новом ASP.NET система идентификации? Или как я могу сбросить, не зная текущего (пользователь забыл пароль)?
8 ответов:
В текущей версии
предполагая, что вы обработали проверку запроса на сброс забытого пароля, используйте следующий код в качестве примера шагов кода.
ApplicationDbContext =new ApplicationDbContext() String userId = "<YourLogicAssignsRequestedUserId>"; String newPassword = "<PasswordAsTypedByUser>"; ApplicationUser cUser = UserManager.FindById(userId); String hashedNewPassword = UserManager.PasswordHasher.HashPassword(newPassword); UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(); store.SetPasswordHashAsync(cUser, hashedNewPassword);
В AspNet Nightly Build
платформа обновлена для работы с токеном для обработки запросов, таких как ForgetPassword. Как только в релизе, ожидается, что простого указания кода.
обновление:
Это обновление просто предоставить более четкие шаги.
ApplicationDbContext context = new ApplicationDbContext(); UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(context); UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(store); String userId = User.Identity.GetUserId();//"<YourLogicAssignsRequestedUserId>"; String newPassword = "test@123"; //"<PasswordAsTypedByUser>"; String hashedNewPassword = UserManager.PasswordHasher.HashPassword(newPassword); ApplicationUser cUser = await store.FindByIdAsync(userId); await store.SetPasswordHashAsync(cUser, hashedNewPassword); await store.UpdateAsync(cUser);
или как я могу сбросить, не зная текущего (пользователь забыл пароль)?
Если вы хотите изменить пароль с помощью UserManager, но не хотите вводить текущий пароль пользователя, вы можете создать токен сброса пароля, а затем использовать его немедленно.
string resetToken = await UserManager.GeneratePasswordResetTokenAsync(model.Id); IdentityResult passwordChangeResult = await UserManager.ResetPasswordAsync(model.Id, resetToken, model.NewPassword);
устаревший
Это был оригинальный ответ. Он работает, но есть проблема. А что если
AddPassword
не удается? Пользователь остается без пароля.оригинальный ответ: мы можем использовать три строки кода:
UserManager<IdentityUser> userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>()); userManager.RemovePassword(userId); userManager.AddPassword(userId, newPassword);
Смотрите также:http://msdn.microsoft.com/en-us/library/dn457095 (v=vs. 111). aspx
Сейчас
вероятно, лучше использовать ответ, что EdwardBrey предложил!--10--> и затем Дэниелрайт позже уточнил пример кода.
на
UserManager
, первый вызов GeneratePasswordResetTokenAsync. Как только пользователь подтвердит свою личность (например, получив маркер по электронной почте), передайте маркер в ResetPasswordAsync.
создать способ в
UserManager<TUser, TKey>
public Task<IdentityResult> ChangePassword(int userId, string newPassword) { var user = Users.FirstOrDefault(u => u.Id == userId); if (user == null) return new Task<IdentityResult>(() => IdentityResult.Failed()); var store = Store as IUserPasswordStore<User, int>; return base.UpdatePassword(store, user, newPassword); }
string message = null; //reset the password var result = await IdentityManager.Passwords.ResetPasswordAsync(model.Token, model.Password); if (result.Success) { message = "The password has been reset."; return RedirectToAction("PasswordResetCompleted", new { message = message }); } else { AddErrors(result); }
этот фрагмент кода взят из проекта AspNetIdentitySample доступно на github
в случае сброса пароля рекомендуется сбросить его путем отправки токена сброса пароля на электронную почту зарегистрированного пользователя и попросить пользователя предоставить новый пароль. Если вы создали легко используемую библиотеку .NET над Identity framework с настройками конфигурации по умолчанию. Вы можете найти подробную информацию на ссылка на блог и исходный код в github.
я думаю, что руководство Microsoft для ASP.NET идентичность-это хорошее начало.
Примечание:
если вы не используете AccountController и wan'T для сброса пароля, используйте
Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
. Если у вас нет того же OwinContext вам нужно создать новыйDataProtectorTokenProvider
какOwinContext
использует. От по умолчанию смотрите наApp_Start -> IdentityConfig.cs
. Должно выглядеть что-то вродеnew DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
.может быть создан следующим образом:
Без Долг:
[HttpGet] [AllowAnonymous] [Route("testReset")] public IHttpActionResult TestReset() { var db = new ApplicationDbContext(); var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(db)); var provider = new DpapiDataProtectionProvider("SampleAppName"); manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>( provider.Create("SampleTokenName")); var email = "test@test.com"; var user = new ApplicationUser() { UserName = email, Email = email }; var identityUser = manager.FindByEmail(email); if (identityUser == null) { manager.Create(user); identityUser = manager.FindByEmail(email); } var token = manager.GeneratePasswordResetToken(identityUser.Id); return Ok(HttpUtility.UrlEncode(token)); } [HttpGet] [AllowAnonymous] [Route("testReset")] public IHttpActionResult TestReset(string token) { var db = new ApplicationDbContext(); var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(db)); var provider = new DpapiDataProtectionProvider("SampleAppName"); manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>( provider.Create("SampleTokenName")); var email = "test@test.com"; var identityUser = manager.FindByEmail(email); var valid = Task.Run(() => manager.UserTokenProvider.ValidateAsync("ResetPassword", token, manager, identityUser)).Result; var result = manager.ResetPassword(identityUser.Id, token, "TestingTest1!"); return Ok(result); }
С Owin:
[HttpGet] [AllowAnonymous] [Route("testResetWithOwin")] public IHttpActionResult TestResetWithOwin() { var manager = Request.GetOwinContext().GetUserManager<ApplicationUserManager>(); var email = "test@test.com"; var user = new ApplicationUser() { UserName = email, Email = email }; var identityUser = manager.FindByEmail(email); if (identityUser == null) { manager.Create(user); identityUser = manager.FindByEmail(email); } var token = manager.GeneratePasswordResetToken(identityUser.Id); return Ok(HttpUtility.UrlEncode(token)); } [HttpGet] [AllowAnonymous] [Route("testResetWithOwin")] public IHttpActionResult TestResetWithOwin(string token) { var manager = Request.GetOwinContext().GetUserManager<ApplicationUserManager>(); var email = "test@test.com"; var identityUser = manager.FindByEmail(email); var valid = Task.Run(() => manager.UserTokenProvider.ValidateAsync("ResetPassword", token, manager, identityUser)).Result; var result = manager.ResetPassword(identityUser.Id, token, "TestingTest1!"); return Ok(result); }
The
DpapiDataProtectionProvider
иDataProtectorTokenProvider
должен быть создан с тем же именем для сброса пароля для работы. Использование Owin для создания токена сброса пароля, а затем создание новогоDpapiDataProtectionProvider
С другим именем не будет работать.код, который я использую для ASP.NET Личность:
Web.Config:
<add key="AllowedHosts" value="example.com,example2.com" />
AccountController.cs:
[Route("RequestResetPasswordToken/{email}/")] [HttpGet] [AllowAnonymous] public async Task<IHttpActionResult> GetResetPasswordToken([FromUri]string email) { if (!ModelState.IsValid) return BadRequest(ModelState); var user = await UserManager.FindByEmailAsync(email); if (user == null) { Logger.Warn("Password reset token requested for non existing email"); // Don't reveal that the user does not exist return NoContent(); } //Prevent Host Header Attack -> Password Reset Poisoning. //If the IIS has a binding to accept connections on 80/443 the host parameter can be changed. //See https://security.stackexchange.com/a/170759/67046 if (!ConfigurationManager.AppSettings["AllowedHosts"].Split(',').Contains(Request.RequestUri.Host)) { Logger.Warn($"Non allowed host detected for password reset {Request.RequestUri.Scheme}://{Request.Headers.Host}"); return BadRequest(); } Logger.Info("Creating password reset token for user id {0}", user.Id); var host = $"{Request.RequestUri.Scheme}://{Request.Headers.Host}"; var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id); var callbackUrl = $"{host}/resetPassword/{HttpContext.Current.Server.UrlEncode(user.Email)}/{HttpContext.Current.Server.UrlEncode(token)}"; var subject = "Client - Password reset."; var body = "<html><body>" + "<h2>Password reset</h2>" + $"<p>Hi {user.FullName}, <a href=\"{callbackUrl}\"> please click this link to reset your password </a></p>" + "</body></html>"; var message = new IdentityMessage { Body = body, Destination = user.Email, Subject = subject }; await UserManager.EmailService.SendAsync(message); return NoContent(); } [HttpPost] [Route("ResetPassword/")] [AllowAnonymous] public async Task<IHttpActionResult> ResetPasswordAsync(ResetPasswordRequestModel model) { if (!ModelState.IsValid) return NoContent(); var user = await UserManager.FindByEmailAsync(model.Email); if (user == null) { Logger.Warn("Reset password request for non existing email"); return NoContent(); } if (!await UserManager.UserTokenProvider.ValidateAsync("ResetPassword", model.Token, UserManager, user)) { Logger.Warn("Reset password requested with wrong token"); return NoContent(); } var result = await UserManager.ResetPasswordAsync(user.Id, model.Token, model.NewPassword); if (result.Succeeded) { Logger.Info("Creating password reset token for user id {0}", user.Id); const string subject = "Client - Password reset success."; var body = "<html><body>" + "<h1>Your password for Client was reset</h1>" + $"<p>Hi {user.FullName}!</p>" + "<p>Your password for Client was reset. Please inform us if you did not request this change.</p>" + "</body></html>"; var message = new IdentityMessage { Body = body, Destination = user.Email, Subject = subject }; await UserManager.EmailService.SendAsync(message); } return NoContent(); } public class ResetPasswordRequestModel { [Required] [Display(Name = "Token")] public string Token { get; set; } [Required] [Display(Name = "Email")] public string Email { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 10)] [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; } }