I have a requirement to force a user to change password after 90 Days. This is working fine with something like the below:
if (memberUser.LastPasswordChangedDate.Date.AddDays(90) < DateTime.Now.Date)
{
return RedirectToAction("MyChangePasswordMethod", "MyController");
}
However another requirement that I have is that the last 5 passwords a user has used cannot be repeated - does asp.net come with anything like this built in? I cant see anything in the aspnet db table where last previous passwords are stored. Will it be a matter of me storing the last password values in my own db table and then doing a compare against the new password field entered against the values for the user in my own custom db table?
As you've spotted there's nothing built in so you'll have to store the previous passwords - make sure they're hashed or encrypted - for a user and check that list to make sure they aren't reusing one. Make sure you use the same salt for the hashing/encryption otherwise you'll never get a match for the same password.
I'd store all their previous passwords. This means you don't have to clear old data out of the table when they hit 5 changes and if the requirement changes to not reuse the last 10 or 15 changes you'll have the data. If you also store the date the password was changed you can build in a check to say no reuse in the last 12 months instead.
As you are storing the hashed/encrypted password and checking against that there's no chance of getting the plain text version out of your system.
I'd have a table of "UserId", "Password" and "DateChanged". Then you can find the last N passwords for this user and compare the hashed/encrypted version of the new password against this list:
var encryptedPassword = MembershipProvider.EncryptPassword(password);
int numberOfReuse = 5; // or configurable
var historiesQuery = (from histories in dataContext.GetTable<PasswordHistory>()
where histories.UserId == userId
orderby histories.PasswordDate descending
select histories.Password).Take<string>(numberOfReuse);
return historiesQuery.Contains<string>(enycryptedPassword);
This returns true if the password has been used already.
To do the date based check:
var encryptedPassword = MembershipProvider.EncryptPassword(password);
DateTime testDate = DateTime.Now.AddMonths(-12); // configurable
var historiesQuery = (from histories in dataContext.GetTable<PasswordHistory>()
where histories.UserId == userId
and histories.PasswordDate >= testDate
orderby histories.PasswordDate descending
select histories.Password);
return historiesQuery.Contains<string>(enycryptedPassword);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With