Introduction

One of the first projects I tackled with .NET, after doing the customary
"Hello World" example, was converting a commercial ASP application into
ASP.NET.

The application tasks were to process, store and acknowledge (via email)
customers' answers to a competition question and to provide a secure area for
company officials to view customer entries and send out bulk mail.

Apart from learning how to implement each step in ASP.NET, I also
restructured the application to make it more object-oriented. For the secure
area of the site I initially more-or-less faithfully reproduced the original
functionality. Then I discovered and investigated ASP.NET's built-in Forms Authentication.

What is authentication?

Authentication is the process of obtaining identification credentials, such as
name and password, from a user and validating those credentials against some
authority. If the credentials are valid, the entity that submitted the
credentials is considered an authenticated identity. Once an identity has been
authenticated, the authorization process determines whether that identity has
access to a given resource.

ASP.NET provides two other methods of authentication that are
platform-specific with respect to the client, whereas Forms Authentication
isn't. A couple of other articles on this site provide more in-depth insight
into Forms Authentication. Here, I just provide the basics and discuss the
issues I needed to address in my authentication process.

The Problem

A company official (also referred to as an administrator) wants to view the list of names and email addresses of the
people who have entered the competition and the answers they've provided. The
official may then perform other tasks, such as running queries or sending bulk
mail.

The security requirements are:

Access to the pages in the secure area requires the official to log in
with a valid user name and password.

Any attempt to navigate to a page in the secure area should redirect a
user to the Login page.

It should not be possible to view any page when the browser is in
offline mode, thereby bypassing security.

There should be a limit on the number of login attempts within any browser
session.

Now, this isn't an e-commerce application. No credit card details are being
processed. It's not necessary to have rock-solid security. Nevertheless it's
worth exploring how security can be breached.

There is no direct navigation from the customer pages to the secure area but
suppose somehow a customer or other user discovers the URL to one of the pages
in the secure area. Then our security mechanism will force them to login. It
will throw them out after a specified number of invalid attempts (say 3). Though they can shut down the browser and try again, but they don't know that.
Hopefully they'll be discouraged. But if not, they'll still have a hard time
discovering the correct user name and password. An administrator will be aware
that they can restart the browser though. So if they forget their login details
they can try again to their heart's content.

A more serious breach would be a malicious user's hacking the web site,
downloading the database and extracting the login details. For this application
we are just using a simple Microsoft Access database. The database is
password-protected so it can't be opened in Access. But you can open the
database in a text editor and perhaps have a poke around (it's mostly gibberish
but it does contain the odd English word fragment). We could encrypt the
database but we haven't.

The last possibility (I think) is a network sniffer's intercepting and
extracting the user name and password as they are transported across the
network. I have not catered for this. But it can be addressed by using Secure
Sockets Layer (SSL) to encrypt the user name and password as they are passed
over the network. If there is a security breach then a hacker would have access
to the names and email addresses of our customers and could send them junk mail. That's
it. In the initial design, at least, company officials cannot directly update
the database via the web. All operations are read-only. So these
restrictions would apply to a hacker too.

Initial Solution

We roll our own authentication functionality. First, define some Session objects in Global.asax.

When the login page is loaded it first checks to see whether the maximum
number of login attempts has been exceeded. If it has the user is redirected to
the "failed login" page.

If the user has not exceeded the maximum number of login attempts the user
name and password are validated against those returned by the AdministratorLogin
object. Here I have just provided a couple of read-only properties which
retrieve the user name and password from a persistent store (in this case, a
database). If all is OK the user can access the customer details page. If not,
an invalid login message is displayed to the user and they can try again up
until the allowable number of attempts.

Once the allowable number of login attempts has been exceeded the user will be
unable to attempt a login again without being redirected to the "failed
login" page.

If the user tries to access any other page in the secure area they are
automatically directed to the login page.
This is because the Page_Load event of each page calls a custom
authentication function that looks like this.

///<spanclass="code-SummaryComment"><summary></span>

Without the first line users can navigate to a secure page when the browser
is offline, if the page is in the history list, which is not what we want!

Forms Authentication Solution

The principal effect of using ASP.NET's Forms Authentication mechanism is
that we no longer need to track the login state. The AuthenticateUser function
above disappears. Nor do we have to write our own code to retrieve the user name
and password from the database. But in order to use the mechanism we must add
some sections to the web.config file in the application root
directory. In the authentication section we replace the default settings with
the following:

The effect of these settings is that all pages in the directory are protected
from access except through the login mechanism. Any files in sub-directories are
also protected unless they contain their own web.config files with different
settings.

In the authentication section, "FwLoginCookie" is the name of the
cookie created by the authentication mechanism. Sometimes we may not want to use
cookies. But for the present purposes these pages are for access only by company
officials. They won't mind having cookies from themselves so to speak!

"Login.aspx" is the
page to be redirected to if a user accesses any other page in the directory. The
credentials section contains a list of valid user names and passwords in clear
format. An alternative is to encrypt them. (There is a framework function that
can do this.) Instead of putting the user name and password in the
web.config file they could be placed in an external XML Users file (or a
database). This is the solution we would go for if we wanted to add new users to
the system.

The location section allows us to override the authentication and
authorization checks for the LoginFail.aspx page. We need to do this so that an
unauthenticated user can be redirected here when their login fails (i.e., after
exceeding the allowable number of login attempts). An alternative is to put the
LoginFail.aspx page in another directory or in a sub-directory with its own
web.config file.

The revised code looks like this. The Session["LoggedIn"] object is
no longer required:

That's it. Again, to make it solid, we should also apply SSL to prevent user
name and password interception.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

My web application has 2 login pages, one for the client and one for admins.

and I set the LoginUrl in the web.config to the client's Login page as you did in your

solution. If one of the admins logged in using the the admins login page and after a while, he logged out . If he clicked on Back button in the browser, he will redirects to the page he was on it instead of redirects to the admin login page.

How Can I enforce the admin to login once he loggedOut ?

Should I add another we.config file in the admin folder to override the default settings in the web.config file that exixts on the root ?

I developed a site with a reserved section based on roles, when I try to access that page i got redirected correctly to the loginpage and on the address bar i see
the ReturnUrl containig the address to point to:

administrator/default.aspx is the page I have to reach
I authenticate succesfully but when the following instruction executes without error:
FormsAuthentication.RedirectFromLoginPage(user, chkRemember.Checked)
i still remain in the same page, only user and pwd disappear

hi every body...i have made a login page .........i want a code in c# to check the username exists or not if it exists then a message should be displayed that user name exists otherwise it should be entered in the database(SQL Server 2000)...can anybody help..........

Hi!
In my application ,startup page is Base.aspx. Base.aspx contains four tabs & an ifrmae. the source of iFrame changes depending upon which tab is clicked. one of tab when clicked of the Base.aspx, then source of iFrame become login.aspx. when valid user is logins, the redirected to BaseTwo.aspx which also contains tabs & a iFrame & source of this iframe changed depending upon tab clicked on BaseTwo.aspx. i want to apply From Authentication in this application. setting web.config is ....

<forms loginUrl="login.aspx" path="/" protection="All"></forms>

now when i run application login page is loaded instead of startup page Base.aspx & also images are not loaded & give some javascript error. when i commented the setting above in web.config file, there is no error & images loaded.

I have some security questions:
* Can we avoid that user opens more than 1 session at the time? How to set web.config file to do that?
* If user leaves his window opened (in online mode) someone can see his pages by clicking explorer button "back". Can we control it without the annoying message "application is attempting to close your window" on logout? (For example in the Page_Load of each protected page we check if his session is still alive?)

Hello All,
i have used the code given in my application, but i am getting errors while writing "FormsAuthentication" and "XMLAuthentication" lines........
cud u pls tell me whole code for the application and the namespaces that shud be included...

Hi!
I am working on one Portal project where I need to send Bulk Email on every thursday Night to the all subscribers. The Portal have have arround 1,000,000 exciting members and as per members there are so many Subscribers.

My Problem is how I Send a bulk email to all the subscribes on every thursday night?

Hi, I need to SetAuthCookie so that within 2 hours, the user doesn't need to type password again when he connects to our website. But after 8 hours, it should be timeout (the user is required to type the password if he connects to our website after 8 hours).

Windows authentication is always better, but is difficult to manage unless you host you own server and a authentication server like Active Directory. Forms authentication is simple and easy to implement with few lines of code.

Hi, I need to SetAuthCookie so that within 8 hours, the user doesn't need to type password again when he connects to our website. But after 8 hours, it should be timeout (the user is required to type the password if he connects to our website after 8 hours).