ASP.NET has three types of authentication services that can be activated for an application: Windows, Forms, and Passport Authentication (and also None which is the default). Windows authentication authorizes requests against NT users or groups. Passport authenticates against the Passport database. And Forms authentication redirects unauthenticated users to a login page where you can secure a directory in your application much like .htaccess. Forms authentication performs all the necessary cookie management.
When performing Forms Authentication to secure one or more directories you need to tell your application the following:
- What type of authentication the application should be using. Allow all users to the application. Create a user credential list where you will store usernames and passwords and tell the application what format passwords will be in.
- Tell the specific directory in your application that it should only authorize the users in your credential list.
- What file to process where users can login and authenticate themselves.
- How to logout a user.
The first code you will need is in your application's main web.config file which tells the
application to use "Forms" authentication and to allow all users (by the special character "*") authorization to your application. It also tells what login page to load if a user is not authenticated and
gives a user/password list to check against.
<system.web>
<authentication mode="Forms">
<forms loginUrl="login.aspx">
<credentials passwordFormat="SHA1">
<user name="test" password="0065C7C7E63B87243AF314C87BCEAA966E89D466"/>
</credentials>
</forms>
</authentication>
<authorization>
<allow users="*" />
</authorization>
</system.web>
|
The Authentication tag's mode attribute can be either, Forms,Windows,Passport or None. In our case it needs to be set to Forms.
The Forms tag not only tells what page to go to if a user is not authenticated, but also the length of time the cookie is in effect (for the current user's session), the path to use for the issued cookie, and specifying the cookie's protection level with the following properties:
- timeout - time in minutes until the cookie expires (default is 30 minutes).
- path - the path to use for the cookie ("/" if the default).
- protection - method used to protect the cookie and has the following values:
- All - uses data validation and encryption to protect the cookie.
- None - no validation or encryption.
- Encryption - uses TripleDES or DES. Can be subject to plaintext attacks.
- Validation - validates that the cookie has not been altered in transit.
The authorization tag can take either allow or deny elements as long as each has a user or roles attribute (multiple values can be separated by commas). Special values are * which specifies all users and ? which specifies only authenticated users.
In your Forms tag is where you specify what users are allowed to be authenticated with the Credentials tag. The Credentials attribute passwordFormat can be either MD5, SHA1, or Clear. It is always best to store your passwords in a Hash format. You can use the example code from the previous article on creating Hash values for storage in the web.config file. Inside the credentials tag you can list as many user and password entries as you need (passwords can also reside in an XML file or database).
After you have made the changes in your applications main web.config file you need to create another web.config file in the directory which you want password protected. Just use the following code:
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
|
It's pretty easy. It's uses the special value of ? to only allow authenticated users to view the contents of that directory.
Now you need a login page so that if an unauthenticated user comes to that directory they will be redirected. The code below can be copied and saved as "login.aspx" and put in your application's root directory (specified by the location property in the forms tag.
<html>
<head>
<title>Login</title>
<script language="C#" runat="server">
void Login_Click(Object sender, EventArgs e) {
if (FormsAuthentication.Authenticate(username.Text, password.Text)){
FormsAuthentication.RedirectFromLoginPage(username.Text, false);
}else{
instructiontext.Text = "You did not enter in the correct username or password";
}
}
</script>
</head>
<body>
<center>
<b>LOGIN</b><br>
<asp:label runat="server" id="instructiontext">
Please enter in your username and your password.
</asp:label>
<form runat="server">
User Name<br>
<asp:textbox id="username" runat="Server"/>
<br>
Password<br>
<asp:textbox id="password" textmode="Password" runat="Server"/>
<br/>
<P>
<asp:button id=login_button onclick="Login_Click" text="Login Now" runat="Server"/>
</form>
</center>
</body>
|
As you can see it is a pretty standard login page with a user and password field and a button which calls a function. In the function we're using the FormsAuthentication class methods Authenticate and RedirectFromLoginPage. Authenticate takes two parameters, a user name and password. It then checks them against the credentials in your application's main web.config file. If the user is authenticated it then calls RedirectFromLoginPage which takes two parameters: userName which is the name of the user which is used for cookie authentication and createPersistentCookie which can be set to either "true" of "false". In our example we are not using a persistent cookie.
That's all you need to password protect a directory in your application!
No more adding in messy if/then statements to headers and footers. It's also scalable if you want to change the authentication method. One question though you might be asking yourself is "Does this work with other files, or only .aspx and ascx files?". The answer is that it works with .aspx and ascx files initially, however can also be used to protect other files like images or documents. This is accomplished by mapping files you want protected to be processed by aspnet_isapi.dll which can be done per application/virtual directory through IIS and adding an application extension mapping like ".jpg" or ."gif". Doing this does cause some additional overhead, but is minimal in comparison to the desired effect.
The last thing you might be asking yourself is how do you clear a users authentication cookie/ticket? This can be done easily by just creating a page called logout.aspx which will destroy all cookies regardless of whether or not they are persistent.
<html>
<head>
<title>Login</title>
<script language="C#" runat="server">
public void Page_Load(Object sender, EventArgs e) {
FormsAuthentication.SignOut();
}
</script>
</head>
<body>
Your are now logged out.
</body>
</html>
|
It just uses the method SignOut (which does not take any parameters) to clear the cookie so a user will need to login again.