In this article I am going to show you how to create a secure login screen for your ASP.NET website – the proper way. I have come across many examples which do not show the correct way of implementing this, so I decided to create my own example and clarify the facts a little.
The Web Pages
Let’s start off by creating our web pages. We need three for this example:
- A Home Page (Home.aspx)
- A Login Page (LogIn.aspx)
- A Members-Only Page (Member.aspx)
So create an ASP.NET Web Application Project and add Home.aspx and LogIn.aspx to the project. Now in your project tree create a new folder and call it Members. Then create Member.aspx under the Members folder. Also under the Members folder, add a new Web Configuration File .
The Home Page
Now let’s go to the Home.aspx and add some code to the page. For the purpose of this example I’m going to keep it simple. Let’s just add a title, a welcome message and a link to the LogIn.aspx page.
The Login Page
The LogIn.aspx page is a little more complicated because we have to add user authentication code here. But first let’s add a Login control to the page, and as before we’ll also add a title and a small message.
As you can see in the above code we have created an event handler for the Login control called LoginControl_Authenticate. This is where we will validate the user’s credentials.
For this example we will validate the credentials using a database (the proper way :)). I am going to use SQL Express since that can be automatically installed with Visual Studio.
If you don’t have it installed you can download it for free from Microsoft. You might also want the SQL Server Management Studio Express so that you can edit database schemas and set user permissions, etc.
We will need to create a database – let’s call it MembershipSite. Then create a table called Users with the following schema:
Obviously for a real-world application the Users table will contain much more fields/columns, but for this example the above table is enough.
Next we must implement the code which will authenticate the website users with the Users table. Below is the event handler of the Login control.
As you can see we are calling a method called ValidateCredentials (which is shown below) to make sure the user exists in the database, and then if the user does exist we are calling FormsAuthentication.RedirectFromLoginPage. The purpose of this method is to redirect the authenticated user to the members’ only page.
The first method in the above code is called IsAlphaNumeric. It accepts one parameter and returns true or false depending on whether the text passed is alphanumeric.
The second method is the ValidateCredentials method which accepts the user name and password and parameters.
Many login pages are targeted by hackers who want to gain access to your website or maybe even bring it down, so that is why I added that first if statement to this method. Before trying to authenticate the user against the database we are making sure that the user name and the password do not exceed 50 characters in length and that the user name does not contain any special characters or symbols which could break an SQL query. Obviously, a password should allow for special characters for it to be secure, so we cannot run the password through the IsAlphaNumeric method.
Next we are building an SQL statement which will count the number of users which have the passed username and password. If none exist the user is not in the system, and if one exists you can authenticate the user. If more than one exists you probably have a problem, but I’m not going to get into how you assign usernames and passwords to new users.
Let’s have a closer look at the SQL query.
As you can see we are not embedding the username and passwords directly into the SQL statement, but instead we are using SQL Parameters (the words with the ‘@’ symbol in front of them.) This makes our system safer because if a hacker tries to perform an SQL Injection, for example, he would not be able to inject any SQL after the quotes in the statement. This is because with SQL Parameters, there are no quotes around string values in an SQL statement. The quotes will be added internally so thay cannot be manipulated by anyone.
Next we are creating a new SQL Connection, and again, we are doing this the proper way. Instead of hard-coding the
connection string, we are getting it from the application’s web.config file by calling:
Now at this point there is no connection string in your app.config file, so let’s create one. Add the following XML to the connectionStrings section of your app.config file, and remember to replace the Data Source. the ID. and Password with your values.
Now that that’s done we can move on to the next part of the ValidateCredentials method, where we are creating the actual SQL Parameters. Note the code we are using when adding the password parameter:
We are calling Hasher.HashString for the password. If you are a regular reader of this blog you would have recognised this class from my previous article – How to create your own C# Hashing Class Library. All the HashString method does is return the hash of the string passed to it.
But still, why are we hashing the password? Well, because we’re doing it the proper way :). It is never advisable to store passwords as free text in the database. You should either encrypt them or hash them. The advantage of hashing is that a hash is irreversible. So if a hacker gets his hands on your database, with all the user passwords inside, he cannot do anything with it. If he tries to login with one of the passwords, our system will just re-hash the hash, and obviously it won’t find a match in the database. For the hacker to log in he must know the user’s password, and since we’re not storing it anywhere, he cannot get it from us.
The rest of the code just opens the connection to the database and executes the SQL query. Then according to the result returned we return true or false .
The Member Page
Similar to the other two pages we created, let’s add a title and a message, but this time also a Logout link.
The message we are displaying on screen contains the user’s login name. The system stored the user’s name automatically when he logged in, and we are using the LoginName control to display it on the page. There is no code involved to show the name, just place the control on your web form and the user name will automatically appear.
We are also using the LoginStatus control which is a hyperlink which either logs a user in or logs him out. The link text displayed depends on whether the user is logged in or not. It is all automatic, and you do not need to add any code, unless obviously you want to customise some stuff.
This page can only be accessed by authenticated users. If the user is unauthenticated and he tries to access the URL for this page directly, ASP.NET will automatically redirect him to the home page.
But, I hear you ask, how does ASP.NET know which page is my home page and which page is my member’s only page, and how does it know that unauthenticated users must be redirected to the home page? Good question. It doesn’t… yet.
For ASP.NET to correctly handle this logic, we must modify both our web.config files.
The Members web.config
The web.config under the Members folder must look like this:
As you can see there is an XML tag called deny and its user attribute is set to “?”. This means that all anonymous users are denied access to any files under the Members folder. Therefore if you are unauthenticated and try to access files under the Members folder, you will be redirected.
The Application web.config
Our final task is to let ASP.NET know where to redirect users when they log in and when they are unauthenticated. To do this we must replace the default line <authentication mode="Windows"/> with the following lines in the main web.config file:
What we are doing here is switching from Windows authentication to Forms authentication mode, and then we are identifying the url the user is redirected to when he logs in, and also the url the user is redirected to if he is not logged in and tries to access the member only area.
And that’s it. I have shown you the proper way to create a login page and authenticate your users.
I hope you enjoyed this article and found it useful. Please feel free to leave your comments below.
You can download the source code for this ASP.NET application at the end of the article but remember it requires Microsoft Visual Studio 2008, although you can easily copy the code to an older version of Visual Studio.
Stay tuned for more articles soon.
Download Login Screen source – 16.5 KB