Question

I was just wondering how I could check (when a user is changing password after the password expires) how I could use (in WebMatrix) an if branch to ensure that the new password does not equal the previous password.

I don't think I want to check for any more password history beyond just the last password used, so as long as I can just check the previous password, I think that will be fine.

I could of course query the database and check, but as the password doesn't get stored in plain text, I know that this won't work, but I also checked on the WebSecurity methods here:

http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity(v=vs.111).aspx

and didn't find anything.

What is the best way to get this done?

Was it helpful?

Solution

Since the password is not stored in the database, there is no way for you to do this, unless you make a note of the password when the user first registers, and whenever they subsequently change it.

The irony here is that by storing the original password (even in an encrypted state), you actually reduce the security of your application.

OTHER TIPS

For any who are interested, I did find a nice workaround to this question, that gets the job done just fine.

Keep in mind, though, that this will only work to check the very last password they had/have.

This is what I implemented:

First, of course, in the log-in page, among other code and after actual log-in, I have the obvious (to check if their password is over 6 months old and require change):

if(WebSecurity.GetPasswordChangedDate(username).AddMonths(6) < DateTime.UtcNow)
{
    WebSecurity.Logout();
    Session["gActionMessage"] = "Your password has expired. Please change your password by visiting \"Login\" then \"Change Password\"";
    Session["gActionMessageDisplayed"] = "not";
    Response.Redirect("~/");
}

Then, I came up with this on the "Change Password" page (actually the redirected page after email verification for password reset token, but you get the idea):

if(WebSecurity.Login(email, newPassword, false) && WebSecurity.UserExists(email) && WebSecurity.GetPasswordChangedDate(email).AddMonths(6) < DateTime.UtcNow)
{
    WebSecurity.Logout();
    errorMessage = "You cannot repeat your last expired password.";
}

The if branch here does three checks:

First, it effectively checks and logs them in if possible based off of what they typed in as their new password.

Secondly, it checks if the user exists (not really sure if I even need this, but whatever).

And lastly, checks to make sure that their password change date is over 6 months old (because the same page is used for "forgot password" stuff, so this just ensures that the right circumstances are met before erring in this way).

So, in short, if their new password is still sufficient to log them in (before it actually gets changed, of course), then it is a repeat and subsequently logs them out and throws the error message at them instead of changing the password. If it is not sufficient to log them in, then it can't be a repeated password, and (so long as it meets any other requirements) the password is then changed.

Hope this helps anyone, who may require a non-repeated password using WebMatrix upon password change, in the future!

Reference the System.Web.Helpers assembly,

Create a custom table called 'UserPasswordHistory' that contains stored hashed passwords in the 'Password' column with an incremented version number in the 'PasswordVersion' column, a row of which is inserted each time a user is registered or a password updated for a given user, the following code works.

var userProfile = db.UserProfiles.First(x => x.UserId == userId);
                var passwords = (userProfile.UserPasswordHistory
                                          .OrderByDescending(x => x.PasswordVersion)
                                          .Take(_configuration.PasswordCountBeforeReuseAllowed))
                                          .Select(x => x.Password);

return passwords.Any(previousPassword => Crypto.VerifyHashedPassword(previousPassword, password));

To answer the question specifically asked _configuration.PasswordCountBeforeReuseAllowed would be set to 1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top