ASP.NET会员更改密码而不知道旧密码

60

评估方法签名时,更改密码时需要知道旧密码。

membershipUser.ChangePassword(userWrapper.OldPassword, userWrapper.Password)

有没有不需要知道旧密码就可以更改密码的方法?

10个回答

117
 string username = "username";
 string password = "newpassword";
 MembershipUser mu = Membership.GetUser(username);
 mu.ChangePassword(mu.ResetPassword(), password);

14
请注意,在 web.config 的成员身份提供程序配置中必须启用 enablePasswordReset 选项。 - Artem Koshelev
1
为什么你不能只使用mu.GetPassword();而不是mu.ResetPassword();呢? - RASMiranda
1
@RMiranda,如果您将加密密码存储在数据库中,则可以使用GetPassword,但是当您应该对其进行哈希处理时,请对其进行哈希处理:http://security.blogoverflow.com/2011/11/why-passwords-should-be-hashed/ - Rob Church
ResetPassword() 方法返回新密码。但是 ChangePassword() 的第一个参数表示旧密码,我不理解。ResetPassword() 方法具体如何工作? - Hgrbz

24
这里的其他答案都是正确的,但可能会使密码处于未知状态。
如果密码不符合Web.Config中规定的要求(最小长度等),则ChangePassword会抛出异常。但只有在调用ResetPassword之后才会失败,因此原始用户或试图更改密码的人将无法知道密码。请在更改密码之前检查复杂性要求以避免此问题:
var user = Membership.GetUser(userName, false);

if ((newPassword.Length >= Membership.MinRequiredPasswordLength) &&
    (newPassword.ToCharArray().Count(c => !Char.IsLetterOrDigit(c)) >=
         Membership.MinRequiredNonAlphanumericCharacters) &&
    ((Membership.PasswordStrengthRegularExpression.Length == 0) ||
         Regex.IsMatch(newPassword, Membership.PasswordStrengthRegularExpression))) {

    user.ChangePassword(user.ResetPassword(), newPassword);
} else {
    // Tell user new password isn't strong enough
}

2
即使在今天,这仍然是一个有价值且深刻的评论(针对我正在处理的遗留代码)。谢谢。 - Sean

14

在更改用户密码之前,您需要重置该密码,并将生成的密码传递给ChangePassword

string randompassword = membershipUser.ResetPassword();
membershipUser.ChangePassword(randompassword , userWrapper.Password)

或者内联:

membershipUser.ChangePassword(membershipUser.ResetPassword(), userWrapper.Password)

为什么你不能只使用membershipUser.GetPassword();而不是membershipUser.ResetPassword();? - RASMiranda
3
@RMiranda - 因为密码不应该以可检索的方式存储,而应该使用哈希算法。请参考链接:http://msdn.microsoft.com/en-us/library/2x0c6sfa(v=vs.110).aspx 和 http://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification - Geoff Appleford
ResetPassword() 返回新密码。但是 ChangePassword() 的第一个参数表示旧密码,我不理解。ResetPassword() 方法如何准确地工作? - Hgrbz

4

尝试使用SimpleMembershipProvider,它更简单:

var token = WebSecurity.GeneratePasswordResetToken("LoginOfUserToChange");
WebSecurity.ResetPassword(token, "YourNewPassword");

4
请注意,在Membership系统配置中,只有在RequiresQuestionAndAnswer属性设置为false时,所有这些解决方案才能起作用。如果RequiresQuestionAndAnswer设置为true,则ResetPassword方法需要传递安全答案,否则会抛出异常。
如果您需要将RequiresQuestionAndAnswer设置为true,则可以使用此解决方法

2

上文提到的代码是有效的:

string username = "username";
string password = "newpassword";
MembershipUser mu = Membership.GetUser(username);
mu.ChangePassword(mu.ResetPassword(), password);

但是您需要在membership provider标签的web.config中设置requiresQuestionAndAnswer="false"。如果它是true,resetpassword方法会生成一个错误“值不能为空”。 在这种情况下,您必须将问题答案作为参数提供给ResetPassword。


1

请使用您想要设置的密码替换文本框中的123456。

 MembershipUser user;     
 user = Membership.GetUser(userName,false);
 user.ChangePassword(user.ResetPassword(),"123456");

0

@Rob Church 是正确的:

这里的其他答案是正确的,但可能会使密码处于未知状态。

然而,与其使用他的手动验证解决方案,我建议尝试使用 ResetPassword from token 方法来更改密码,并捕获并显示错误:

var user = UserManager.FindByName(User.Identity.Name);
string token = UserManager.GeneratePasswordResetToken(user.Id);
var result = UserManager.ResetPassword(user.Id, token, model.Password);
if (!result.Succeeded){
    // show error
}

这个话题是使用旧的Membership。但是你的代码来自新的Asp.Net Identity。 :) - Jawand Singh

0
string username = "UserName";
string userpassword = "NewPassword";
string resetpassword;
    
MembershipUser mu = Membership.GetUser(username, false);

if (mu == null){
    Response.Write("<script>alert('Invalid Username!')</script>"); 
}

else{
    resetpassword = mu.ResetPassword(username);
    if (resetpassword != null){
         if (mu.ChangePassword(resetpassword, userpassword)){
             Response.Write("<script>alert('Password changed successfully!')</script>"); 
         }
    }
    else{
           Response.Write("<script>alert('Oh some error occurred!')</script>"); 
        }
    }

欢迎来到StackOverflow。请提供一些解释。 - Peter Csala

0
 string username = "UserName";
 string userpassword = "NewPassword";   
 MembershipUser mu = Membership.GetUser(username, false);
 mu.ChangePassword(mu.ResetPassword(username), userpassword);

这是要作为对您其他答案的编辑吗?请使用帖子下方的编辑链接并删除此回复。 - LarsTech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接