For the base of my application I decided to start with a template that had the basic layout and login system in place to save some time and allows me to focus on the heart of my application. I went with the ASPNETMVC5WebApp template which is a project for creating a jQuery mobile application using ASP.NET MVC5 with Razor Syntax (CSHTML) and Entity Framework 6 (EF6). A mobile centric application works best for me as I intend to use my application on my cell phone the majority of time to add/update/view entries. I decided against a mobile app since I do want to be able to access from a computer as well.
During the process of developing the login system for my application I determined modifications were required in the database design; two additional columns in the User table, LastLogin and InitializationVector as well as an additional table, AccessCode. My database design now looks like the following (the original):
Security & Authentication
The InitilizationVector and Salt columns store information required in decryption of a users password, which are generated and saved to the database when the user registers and creates a password for the first time or when a user resets their password. I use the System.Security.Cryptography.Rfc2898DeriveBytes implementation of PBKDF2 to encrypt and decrypt passwords which implements password-based key derivation functionality by using a pseudo-random number generator based on HMACSHA1.
Forms authentication is used for logging in/out. In order to store the users id as well as the username; I set the username parameter of FormsAuthentication’s setAuthCookie() method to include the user id. By making the string “id:username” I can parse out the relevant information needed, by retrieving the User.Identity.Name variable, so the data can persist between browser sessions. This is so that I can satisfy future requests by retrieving the User.Identity.Name variable and parsing out the section I need.
I implemented a twist on the registration process in the template since I do not want just anybody registering to use my application. I modified the registration form to accept an access code and only allow the registration to succeed if the access code is valid. To validate the code I created a table, AccessCode in the diagram, which stores access codes along with their corresponding expiration date and a brief description so that I know whom it is for. Presently I would enter this data manually through phpMyAdmin rather than implementing an admin section to do this as I do not foresee this being a frequent occurrence.
When a user registers a check is first made to see if the provided access code exists and if it does a check to see if it has expired is done; if it expired then a message is presented to the user, the account is not created and the access code is deleted. When valid the user is created provided all other validation methods are successful and then the access code is deleted; otherwise the user is informed of validation errors and can attempt again, since the access code is still valid.
When the user logs in the current value of LastLogin, a DateTime column for storing the date and time of the users last log in, is retrieved and a corresponding message is displayed to the user notifying them of when they last logged in.
Odd Issues I Overcame
I was running into the Entity Framework exception “System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See ‘EntityValidationErrors’ property for more details” and found a blog post to follow which provided me the details I needed when debugging to solve the issue.
I wanted to use ASP.NET Identity 2.0 / Membership, potentially with roles (though presently all users are equal), but I decided to make it work with MySQL (as I’d have to write my own provider, etc. since the default only supports MS SQL Server) added a layer of complexity that doesn’t seem warranted at this stage.