asp.net membership change password without knowing old one - asp.net

Evaluting the method signature, it is required to know old password while changing it.
membershipUser.ChangePassword(userWrapper.OldPassword, userWrapper.Password)
Is there any way to change password without knowing old one.

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

The other answers here are correct, but can leave the password in an unknown state.
ChangePassword will throw exceptions if the password doesn't meet the requirements laid out in Web.Config (minimum length, etc.). But it only fails after ResetPassword has been called, so the password will not be known to the original user or to the person who's tried to change it. Check for complexity requirements before changing the password to avoid this:
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
}

You need to reset the user's password before changing it, and pass in the generated password to ChangePassword.
string randompassword = membershipUser.ResetPassword();
membershipUser.ChangePassword(randompassword , userWrapper.Password)
or inline:
membershipUser.ChangePassword(membershipUser.ResetPassword(), userWrapper.Password)

Try to use SimpleMembershipProvider it's easier:
var token = WebSecurity.GeneratePasswordResetToken("LoginOfUserToChange");
WebSecurity.ResetPassword(token, "YourNewPassword");

Please note, all these mentioned solutions will only work if the RequiresQuestionAndAnswer property is set to false in Membership system configuration. If RequiresQuestionAndAnswer is true then the ResetPassword method needs to be passed the security answer, otherwise it will throw an exception.
In case you need RequiresQuestionAndAnswer set to true, you can use this workaround

This code mentioned on posts above is working:
string username = "username";
string password = "newpassword";
MembershipUser mu = Membership.GetUser(username);
mu.ChangePassword(mu.ResetPassword(), password);
But you have to set requiresQuestionAndAnswer="false" in web.config in membership provider tag. If it is true, resetpassword method generate an error "Value can not be null".
In this case you must supply question answer as parameter to ResetPassword.

Use the password you want to set from textbox in place of 123456.
MembershipUser user;
user = Membership.GetUser(userName,false);
user.ChangePassword(user.ResetPassword(),"123456");

#Rob Church is right:
The other answers here are correct but can leave the password in an
unknown state.
However, instead of his solution to do the validation by hand, I would try to change the password using the ResetPassword from token method and catch and show the error:
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
}

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>");
}
}

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

Related

Bcrypt Verify always returning false

[HttpPost("signUp")]
public async Task<ActionResult<Users>> PostUserRegister(Users user)
{
if (userEmailExists(user.Email))
{
return BadRequest();
}
string salt = BC.GenerateSalt(12);
// hash password
user.Password = BC.HashPassword(user.Password, salt);
_context.Database.ExecuteSqlRaw("EXECUTE dbo.UserRegister #userName, #firstName, #lastName, #Password, #userEmail, #gender, #dob",
new SqlParameter("#userName", user.UserName.ToString()),
new SqlParameter("#firstName", user.FirstName.ToString()),
new SqlParameter("#lastName", user.LastName.ToString()),
new SqlParameter("#Password", user.Password.ToString()),
new SqlParameter("#userEmail", user.Email.ToString()),
new SqlParameter("#gender", user.Gender.ToString()),
new SqlParameter("#dob", user.Dob));
/* var format = "dd/MM/yyyy";
var date = DateTime.ParseExact(user.Dob, format);*/
return Ok(user);
//_context.Users.Add(users);
//await _context.SaveChangesAsync();
//return CreatedAtAction("GetUsers", new { id = users.UserId }, users);
}
Im siging a new user up like this. Hashing the password using Bcrypt.
using BC = BCrypt.Net.BCrypt;
[HttpPost("login")]
public async Task<ActionResult<Users>> PostUserLogin(Users user)
{
// get account from database
var account = _context.Users.SingleOrDefault(x => x.Email == user.Email);
// check account found and verify password
if (account == null || !BC.Verify(user.Password, account.Password))
{
// authentication failed
return Unauthorized(user);
}
else
{
// authentication successful
return Ok(user);
}
Then I try to verify the password in the login function. When i debug to see the values of user.Password and account.Password they are correct. the user.Password is equal to the password the user entered to register and the account.Password is the Hashed password stored in the database. I was trying to follow this tutorial ASP.NET Core 3.1 - Hash and Verify Passwords with BCrypt
I have read the blog you provided. And I think we should double check below points.
The format of Password in your db,if the orginal password is 11, then the value stored should like :
$2a$12$NTuJLk9/xZnlxP.oFj1mu.1ZypqYP4YuS1QbTBy7ofJwzKLSEEVBq
In this line BC.Verify(user.Password, account.Password),
The value of user.Password
user.Password == 11
And the value of account.Password
account.Password == $2a$12$NTuJLk9/xZnlxP.oFj1mu.1ZypqYP4YuS1QbTBy7ofJwzKLSEEVBq
Please double check it, if you still have some issue, you can add the picture with debugging result.
i have same problem with bCrypt like you.
The main problem was much simpler than I thought. The main reason for this was that I used uppercase and lowercase letters when I received and saved the password.
I Fixed this problem with make my password input to lower and save it to db
And When i want to verify it , i make the password lowercase again .
user.Password = BC.HashPassword(user.Password.ToLower(), salt);
and when you want to Verify , use it like this:
if (account == null || !BC.Verify(user.Password.ToLower(),account.Password))
I Think This is your question Answer.

Check if a password is valid using ASP.NET Identity 2

On my website, I give the administrators the possibility to change someone's password without entering the old one. I do the following:
userManager.RemovePassword(oldUser.Id);
userManager.AddPassword(oldUser.Id, newPassword);
However, this changes the password only if the newPassword string complies with the password policy set in the configuration files. AddPassword seems to fail silently when the new password does not fulfil the requirements.
Is there some simple way to check if a password is valid according to the current policy, apart from the obvious "manual procedure" (check how many upper/lowercase chars there are, how many digits, etc.). I'm looking for something like
bool valid = IsPasswordValid("pass");
You may be able to use the PasswordValidator.ValidateAsync() method to determine if a password meets the criteria defined in your UserManager :
var valid = (await UserManager.PasswordValidator.ValidateAsync("pass")).Succeeded;
You can simply use PasswordValidator to check for password validity and errors as shown below:
var passwordValidator = new PasswordValidator<IdentityUser>();
var result = await passwordValidator.ValidateAsync(_userManager, null, "your password here");
if (result.Succeeded)
{
// Valid Password
}
else
{
// Check the error messages in result.Errors
}
Above solution works for Asp.Net Core 2.2
In Net.Core 2.2, I did this. I collect the errors into a string list as I send them back via JSON using a mechanism that standard throughout my application. Thanks to cularbytes
List<string> passwordErrors = new List<string>();
var validators = _userManager.PasswordValidators;
foreach(var validator in validators)
{
var result = await validator.ValidateAsync(_userManager, null, newPassword);
if (!result.Succeeded)
{
foreach (var error in result.Errors)
{
passwordErrors.Add(error.Description);
}
}
}

Reset Password Strategy

I have a custom Register form which includes a security question and answer - works fine.
However, I have the following reset password logic which only works if the requiresQuestionAndAnswer property is set to false in my Web.Config file. Can someone show me a recommended way to code the question and answer logic into my ResetPassword code-behind? Is another trip to the DB necessary here?
public void ResetPassword_OnClick(object sender, EventArgs args)
{
string newPassword;
u = Membership.GetUser(UsernameTextBox.Text, false);
newPassword = u.ResetPassword();
if (newPassword != null)
{
Msg.Text
= "Password reset. Your new password is: "
+ Server.HtmlEncode(newPassword);
}
else
{
Msg.Text
= "Password reset failed. Please re-enter your values.";
}
}
I found the answer here:
MembershipUser.PasswordQuestion Property
"If RequiresQuestionAndAnswer is true, then the password answer for a membership user must be supplied to the GetPassword and ResetPassword methods."

ResetPassword method in ASP.NET 4.0

The ResetPassword method is able to reset the old password, but user is unable to login with the new password generated by ResetPassword method. Code:
String user =(((TextBox)PasswordRecovery2.Controls[0].FindControl("UserName")).Text).ToString();
String newPassword = clsStatic.RandomString(10, false);
MembershipUser username = Membership.GetUser(user);
String resetPassword = username.ResetPassword();
username.ChangePassword(resetPassword, newPassword);
Does ChangePassword return true or false?
I bet your random function returns a password that doesn't meet the criteria specified in your web.config membership section.
Since ResetPassword already gives you a new valid password why do you have to generate another one?
Your new random password generation should be ideally one of these
// this will automatically take care of all password criteria
string newPassword = Membership.GeneratePassword(10, 0);
Or
//for generating alpha numeric password only
string newPwd = Guid.NewGuid().ToString().Substring(0, 11).Replace("-", "");
Your code is fine otherwise.

How do you change a hashed password using asp.net membership provider if you don't know the current password?

Problem, there's no method:
bool ChangePassword(string newPassword);
You have to know the current password (which is probably hashed and forgotten).
This is an easy one that I wasted too much time on. Hopefully this post saves someone else the pain of slapping their forehead as hard as I did.
Solution, reset the password randomly and pass that into the change method.
MembershipUser u = Membership.GetUser();
u.ChangePassword(u.ResetPassword(), "myAwesomePassword");
You are not able to change the password if the requiresQuestionAndAnswer="true"
I got the work around for this
Created two membership providers in web.config
i am using the AspNetSqlMembershipProviderReset provider for reseting the password since it has the requiresQuestionAndAnswer= false where as AspNetSqlMembershipProvider is the default provider used.
i wrote the following code to reset the password for the user.
public bool ResetUserPassword(String psUserName, String psNewPassword)
{
try
{
// Get Membership user details using secound membership provider with required question answer set to false.
MembershipUser currentUser = Membership.Providers["AspNetSqlMembershipProviderReset"].GetUser(psUserName,false);
//Reset the user password.
String vsResetPassword = currentUser.ResetPassword();
//Change the User password with the required password
currentUser.ChangePassword(vsResetPassword, psNewPassword);
//Changed the comments to to force the user to change the password on next login attempt
currentUser.Comment = "CHANGEPASS";
//Check if the user is locked out and if yes unlock the user
if (currentUser.IsLockedOut == true)
{
currentUser.UnlockUser();
}
Membership.Providers["AspNetSqlMembershipProviderReset"].UpdateUser(currentUser); return true;
}
catch (Exception ex)
{
throw ex;
return false;
}
}

Resources