The Problem
- I have a pre-defined
[StringLength()]
and[RegularExpression()]
constraint on my Code-First Model. - The
[StringLength()]
requirement is 8-16 characters - The
[RegularExpression()]
constraint for the password is in a different format from the encrypted password.- The password is encrypted before being shoved into the database.
- The encrypted password is 70 characters in length, which is higher than the 8-16 character limit defined in the Model.
- I am required to use
e.Encrypt()
, meaning I cannot use the default ASP.NET hashing algorithm.
I've searched high and low, but have yet to find the correct answer.
My Code
I have a function that allows a user to register an account. It looks like this:
[HttpPost]
public ActionResult Register([Bind(Include="Username,Password,EmailAddress")] UserModel user)
{
if (TryUpdateModel(user))
{
// Set password to a different format than Model's designated Regex
user.Password = e.Encrypt(user.Password);
context.Entry(user).State = EntityState.Added;
context.SaveChanges();
return RedirectToAction("Login", "Account");
}
return View();
}
In my UserModel.cs
file, I have the following constraints:
[Required]
[DataType(DataType.Password)]
[StringLength(16, MinimumLength = 8, ErrorMessage = "Must be between 8 and 16 characters.")]
[RegularExpression("^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]", ErrorMessage = ErrorMessage_PasswordRegex)]
public string Password { get; set; }
Again, the hashed password is in a completely different format. Therefore, I cannot update it because it throws a DbEntityValidationException
. This [RegularExpression()]
is for the format of the user's password. I need to be able to bypass or suspend the password's Regex constraint.
What I have done to remedy this
I've removed the [RegularExpression()]
requirements, and upped the [StringLength()]
to 70, which is the length of my password hash.
However, I don't want to allow users to input 70 characters of text. This seems like a cheap hack, and I feel that there should be a better way to do this. Any ideas?
Here's an example:
We've got different requirements for user input than what our database requires. We might need more user input which we will programmatically act upon.
The EF model
Now here's the class we use to capture user input
Now we transform and map values.
The user won't know what to use for
Id
and the database doesn't have need forConfirmPassword
. We can also transform what the user originally entered as a password.