Reset Password Strategy - asp.net

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."

Related

approve user umbraco membership system

hi i am working on Umbraco(6.1.2) membership system
ive made login ,registration, and authentication page
after registeration user is redirected to authentication page with token_id
now i want to set this user approved for this purpose i write the following code
but there is some error check it
string uname = Request.QueryString["a"];
string uguid = Request.QueryString["b"];
MembershipUser thisUser = Membership.GetUser(uname);
if (thisUser != null)
{
if (!thisUser.IsApproved)
{
MemberProfile mp = MemberProfile.GetUserProfile(uname);
if (mp != null)
{
if (mp.AuthGuid == uguid)
{
thisUser.IsApproved = true;
Membership.UpdateUser(thisUser);
lblMessage.Text = "Thank you for confirming your email address";
}
else
{
lblMessage.Text = "Error confirming your email address";
}
}
else
{
lblMessage.Text = "Error confirming your email address";
}
}
else
{
lblMessage.Text = "Email address is already confirmed";
}
}
control is return to else condition from this condition "if (!thisUser.IsApproved)"
and also if i reverse the condition it gets into if block and executes all commands without errors but still not mark user as approved
plz help me
Refrence:Authenticating new members before activating
I had problem with approved as well.
Now I just use this in my code:
MembershipUser user = Membership.GetUser(nodeIdOrUsername);
user.IsApproved = true;
Membership.UpdateUser(user);
You may also need to add a property to your Member type, eg. isApproved and then add it to your provider in web.config in profile > properties section:
<add name="isApproved" allowAnonymous="false" provider="UmbracoMembershipProvider" type="System.Boolean"/>
and then extend ProfileBase and added an Approved property.
In web.config in membership > provider section add this property to your provider key eg.:
<add name="UmbracoMembershipProvider" type="umbraco.providers.members.UmbracoMembershipProvider" umbracoApprovePropertyTypeAlias="isApproved" umbracoLockPropertyTypeAlias="isLocked" ... />
I can't remember for sure but I think without it it didn't work.
I hope this will be of any use.

How can i validate password for user login

I have the following code to check for valid users:
protected void Login_LoginError(object sender, EventArgs e) {
//See if this user exists in the database
MembershipUser userinfo = Membership.GetUser(Login.UserName);
if (userinfo == null || !userinfo.IsApproved || userinfo.IsLockedOut) {
//The user entered an invalid username/password...
Login.FailureText = "Invalid User/Password";
} else {
Login.FailureText = string.Empty;
}
}
This code doesn't show the failure text when the password is wrong for users, I need code-behind logic for validating both the user and password! Any suggestions appreciated.
You should use the Authenticate handler on the login control. For more reading see this link
If you're using the out of the box MembershipProvider you can authenticate your user with the Membership.ValidateUser method in the Authenticate handler.

asp.net membership change password without knowing old one

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

Is Roles.IsUserInRole behaving as expected in the following simple scenario?

In a custom role provider (inheriting from RoleProvider) in .NET 2.0, the IsUserInRole method has been hard-coded to always return true:
public override bool IsUserInRole(string username, string roleName) { return true; }
In an ASP.NET application configured to use this role provider, the following code returns true (as expected):
Roles.IsUserInRole("any username", "any rolename"); // results in true
However, the following code returns false:
Roles.IsUserInRole("any rolename"); // results in false
Note that User.IsInRole("any rolename") is also returning false.
Is this the expected behavior?
Is it incorrect to assume that the overload that only takes a role name would still be invoking the overridden IsUserInRole?
Update: Note that there doesn't seem to be an override available for the version that takes a single string, which has led to my assumption in #2.
I looked at Roles.IsUserInRole(string rolename) in .net reflector, and it resolves to the following:
public static bool IsUserInRole(string roleName)
{
return IsUserInRole(GetCurrentUserName(), roleName);
}
I would take a look at your current user. Here's why:
private static string GetCurrentUserName()
{
IPrincipal currentUser = GetCurrentUser();
if ((currentUser != null) && (currentUser.Identity != null))
{
return currentUser.Identity.Name;
}
return string.Empty;
}
I would be willing to bet this is returning an empty string because you either don't have a Current User, or its name is an empty string or null.
In the IsUserInRole(string username, string roleName) method, there is the following block of code right near the beginning:
if (username.Length < 1)
{
return false;
}
If your GetCurrentUserName() doesn't return anything meaningful, then it will return false before it calls your overridden method.
Moral to take away from this: Reflector is a great tool :)
Also beware if you have selected cacheRolesInCookie="true" in the RoleManager config. If you have added a new role to the database, it might be looking at the cached version in the cookie.
I had this problem and the solution was to delete the cookie and re-login.
This may help someone - be aware:
If you are using the login control to authenticate - the username entered into the control becomes the HttpContext.Current.User.Identity.Name which is used in the Roles.IsUserInRole(string rolename) and more specifically - the membership's GetUser() method. So if this is the case make sure you override the Authenticate event, validate the user in this method and set the username to a value that your custom membership provider can use.
protected void crtlLoginUserLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
bool blnAuthenticate = false;
string strUserName = crtlLoginUserLogin.UserName;
if (IsValidEmail(strUserName))
{
//if more than one user has email address - must authenticate by username.
MembershipUserCollection users = Membership.FindUsersByEmail(strUserName);
if (users.Count > 1)
{
crtlLoginUserLogin.FailureText = "We are unable to determine which account is registered to that email address. Please enter your Username to login.";
}
else
{
strUserName = Membership.GetUserNameByEmail(strUserName);
blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);
//setting the userLogin to the correct user name (only on successful authentication)
if (blnAuthenticate)
{
crtlLoginUserLogin.UserName = strUserName;
}
}
}
else
{
blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);
}
e.Authenticated = blnAuthenticate;
}

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