Security and Authentication Using ASP Sessions
One of the most basic tasks in web design is to restrict access to certain pages of the site. There are many ways to do this, and each method makes certain tradeoffs between three different elements:
- Strength of security
- Ease of implementation
- Ease of maintenance
Using Active Server pages, you can create password-protected pages without having to create new user accounts on your server, and without having to set up a database. You can click here if you'd like to see an example of some protected pages. The password you will need to log in is "animals" (without the quotation marks). To download a .zip file containing the code for those pages, click here.
The method I'm going to describe here is designed to excel at #2: It's very easy to implement. It's not suited for a site that requires high security. If, for example, you have a site that will include important personal information (social security numbers, for example), you should not use this method. Similarly, if you have a site which will require differentiating many different users, or which will require administrators to be able to reset passwords remotely, forget this method. This is dirt-simple security: users will need to supply a password, but they won't need a username, and all users accessing the secure area will see the same content, have the same rights, and supply the same password.
Where would you use something like this? Suppose I want to share some family photos. I don't want just anyone to be able to see them, but I would like to let several friends and family members see them. I don't, however, want every person to have to remember both a username and password, and there is no reason why I need to use a different password for each user.
The most common way of solving this simple problem involves storing a list of users and passwords in a database. When someone attempts to log in, the server queries the database and determines whether or not the username/password combination is valid. That's a technically elegant solution... but it's still overkill.
Here's the thing: you don't really need a database. You can store the password in the .asp code. Why should I bother with storing a database on the server, or configuring a data connection? Granted, it's not really particularly hard, but it does add a layer of needless complexity: in order to implement the standard solution, I need to either have access to an existing database on the server, or I need to have access to the file system so that I can store an .mdb or some other data file in a location which is not accessible via HTTP.
Real programmers are cringing as they read this. "Hard coding usernames and passwords into your ASP files is a terrible thing to do! You should never have to modify code to change your data. There should always be a separation between the data, and the logic!"
That's a valid theoretical argument. But ditch the dogma, and look at the underlying reality: the conventional solution is harder to implement, and in reality, it is no easier to maintain.
With the asp-only solution, if you want to change the password, all you have to do is download one file, edit one word, and upload it back to the server. How hard is that?
With a database-driven site, you will either need to build an administrative page that will allow you to edit passwords via a web interface, or you will need access to the database managment interface on the server, or download your database file and edit it locally, then upload it again. (You DON'T let anyone install Access on your server, do you???) And you'll probably also need to reset the file permissions on the file, if you have your server locked down reasonably well. Either way, you will need greater access to the server than what you would need if you were storing the password in the ASP code.
The asp-only solution involves only a handful of elements: a login form, an authentication page, and a short snippet of code that will go at the top of each protected page.
It works like this: the login form sends the user-supplied password to the authentication page, which checks to see if the password is correct. If it is, a session variable is set to indicate that the user has successfully logged in. On each "protected" page, the asp code at the top of the page checks the session variable. If they are logged in, the page is rendered; if not, they are redirected to the login form.
There's one other trick built into these pages: asp code at the top of each page also sets a session variable to indicate which page the user was trying to access. For example, in the animal example pages on this site, there are three protected pages: a home page, a dog page, and a cat page. If the user initially goes to the login page, they'll be sent to the home page once they've logged in. But if they try to go directly to the cat page without first logging in, they will be redirected to the login page. As soon as they supply the correct password, however, they will be sent to the cat page, without having to go to the home page first.
I've kept the code in the sample pages as bare as possible, so that it's easier to understand. There are a number of things I'd do differently before deploying these pages in a production environment; for example, I would not typically keep "action" pages (like the authentication page and the logout page) in the same directory with the content pages. And, of course, I'd typically create more elegant-looking pages, and apply CSS styles... but all of that would just make the sample code bigger and somewhat more difficult to read.
Drawbacks to this method? As noted above, it's not all that secure. If you are using HTTP, your password would be sent to the server in clear text. (However, since this method does not require configuring a corresponding user account on the server, the risk there is less than using directory security and basic authentication.) The biggest drawback to this method is that it's written in old-fashioned ASP, instead of .Net. Support for ASP is not as widespread as it once was; in Windows Server 2003, for example, it's turned off by default. Overall, .Net provides a much better architecture for the web. Anyone who has worked with ASP extensively knows that complex .asp pages can become an almost indecipherable mess of HTML and VBScript. For very basic projects, however -- like our dirt-simple authentication -- asp pages are simpler to create, and simpler to maintain.