I have this code for changing a user\'s password when they click the password reset button (with extra code to log to ELMAH so I can try to figure out what is going wrong).
Hmm, I've always used
bool MembershipUser.ChangePassword(string oldPassword, string newPassword)
I've never had an issue with it returning true and the password not being changed correctly. As fas as I can tell your code looks ok. It is difficult to follow, with all the Elmah noise in there. (you might want to remove it or replace with a simple log call so it's easier to follow).
Verify that the string id that you pass as an argument corresponds to the UserId of the intended user. You might be sending the userId from some other user and changing that users password instead.
If the user needs to reset his password, there is a chance their account has been locked out from too many invalid attempts. If this is the case, then the password is being reset successfully, but the user cannot log in until the lockout condition is cleared.
Try checking MembershipUser.IsLockedOut:
Users are most commonly locked out and cannot be validated by the ValidateUser method when the MaxInvalidPasswordAttempts is reached within the PasswordAttemptWindow.
To set this property to false and let the user try to log in again, you can use the UnlockUser method.
Edit
Did you also check IsApproved? Authentication will fail is this is false
for the user.
Also, assuming by default membership provider, you mean the SqlMembershipProvider, can you run the following query against your database and make sure everything looks correct?
select IsApproved, IsLockedOut, FailedPasswordAttemptCount
from aspnet_Membership
where ApplicationId = @yourApplicationId and UserId = @userId
Try executing the query before attempting to sign in to verify IsApproved
and IsLockedOut
are ok. Also note the value for FailedPasswordAttemptCount
.
Try signing in, and then run the query again. If signin fails, has the value for FailedPasswordAttemptCount
been incremented?
You could also look at PasswordFormat
in the aspnet_Membership table and make sure it is the correct value depending on the format you are using (0 for Clear, 1 for Hashed, and 2 for Encrypted).
Edited - following answer is false see comments
So wait are you trying to locate someone by a Guid? By doing
Guid userId = new Guid(id);
You are practically creating a guaranteed to be unique ID. So my guess is you are never finding a user and you are resetting a password successfully for nobody. Can you not just find them by the id parameter you pass in?
This works for me:
<%@ Page Title="Change Password" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="ChangePassword.aspx.cs" Inherits="WebPages.Account.ChangePassword" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
Change Password
</h2>
<p>
Use the form below to change your password.
</p>
<p>
New passwords are required to be a minimum of <%= Membership.MinRequiredPasswordLength %> characters in length.
</p>
<asp:ChangePassword ID="ChangeUserPassword" runat="server" CancelDestinationPageUrl="~/" EnableViewState="false" RenderOuterTable="false"
OnChangedPassword="ChangeUserPassword_ChangedPassword">
<ChangePasswordTemplate>
<span class="failureNotification">
<asp:Literal ID="FailureText" runat="server"></asp:Literal>
</span>
<asp:ValidationSummary ID="ChangeUserPasswordValidationSummary" runat="server" CssClass="failureNotification"
ValidationGroup="ChangeUserPasswordValidationGroup"/>
<div class="accountInfo">
<fieldset class="changePassword">
<legend>Account Information</legend>
<p>
<asp:Label ID="CurrentPasswordLabel" runat="server" AssociatedControlID="CurrentPassword">Old Password:</asp:Label>
<asp:TextBox ID="CurrentPassword" runat="server" CssClass="passwordEntry" TextMode="Password"></asp:TextBox>
<asp:RequiredFieldValidator ID="CurrentPasswordRequired" runat="server" ControlToValidate="CurrentPassword"
CssClass="failureNotification" ErrorMessage="Password is required." ToolTip="Old Password is required."
ValidationGroup="ChangeUserPasswordValidationGroup">*</asp:RequiredFieldValidator>
</p>
<p>
<asp:Label ID="NewPasswordLabel" runat="server" AssociatedControlID="NewPassword">New Password:</asp:Label>
<asp:TextBox ID="NewPassword" runat="server" CssClass="passwordEntry" TextMode="Password"></asp:TextBox>
<asp:RequiredFieldValidator ID="NewPasswordRequired" runat="server" ControlToValidate="NewPassword"
CssClass="failureNotification" ErrorMessage="New Password is required." ToolTip="New Password is required."
ValidationGroup="ChangeUserPasswordValidationGroup">*</asp:RequiredFieldValidator>
</p>
<p>
<asp:Label ID="ConfirmNewPasswordLabel" runat="server" AssociatedControlID="ConfirmNewPassword">Confirm New Password:</asp:Label>
<asp:TextBox ID="ConfirmNewPassword" runat="server" CssClass="passwordEntry" TextMode="Password"></asp:TextBox>
<asp:RequiredFieldValidator ID="ConfirmNewPasswordRequired" runat="server" ControlToValidate="ConfirmNewPassword"
CssClass="failureNotification" Display="Dynamic" ErrorMessage="Confirm New Password is required."
ToolTip="Confirm New Password is required." ValidationGroup="ChangeUserPasswordValidationGroup">*</asp:RequiredFieldValidator>
<asp:CompareValidator ID="NewPasswordCompare" runat="server" ControlToCompare="NewPassword" ControlToValidate="ConfirmNewPassword"
CssClass="failureNotification" Display="Dynamic" ErrorMessage="The Confirm New Password must match the New Password entry."
ValidationGroup="ChangeUserPasswordValidationGroup">*</asp:CompareValidator>
</p>
</fieldset>
<p class="submitButton">
<asp:Button ID="CancelPushButton" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"/>
<asp:Button ID="ChangePasswordPushButton" runat="server" CommandName="ChangePassword" Text="Change Password"
ValidationGroup="ChangeUserPasswordValidationGroup"/>
</p>
</div>
</ChangePasswordTemplate>
<SuccessTemplate>
<div class="accountInfo">
<fieldset class="changePassword">
<legend>Password changed</legend>
<p>
Your password has been changed. A confirmation e-mail has been sent to you.
</p>
</fieldset>
</div>
</SuccessTemplate>
</asp:ChangePassword>
</asp:Content>