Forms Authentication allows you to authenticate the user against synthetic accounts. In other words, it liberates authentication from the Windows user accounts and lets the user information be centralized in a backend database or even placed directly in config files in the application. You can still take advantage of the kind of role management available with Windows accounts. (See the section “Working with Roles” later in this chapter).
To enable Forms Authentication with the defaults, simply set the value of the mode attribute of authentication to Forms. Code Listing 8-3 demonstrates enabling Forms Authentication and setting a custom cookie name.
Code Listing 8-3: Forms Auth Web.config
<configuration>
<system.web>
<authentication mode="Forms" >
<forms name="CookieName" loginUrl="login.aspx" />
</system.web>
</configuration>
When using ASP.NET Forms Authentication, each request is checked against authentication tickets from a FormsAuthenticationTicket object. In mobile pages, the ticket might be carried in the query string (the string at the end of the URL preceded by a ?); otherwise, it is carried in the cookies. If it is not found or has expired, the user is redirected to the loginUrl specified in the forms element. The default value of loginUrl in machine.config is login.aspx. The purpose of the loginUrl page is to ask the user for the user name and password, and if satisfied, issue a ticket. Just like Basic Windows Authentication, ASP.NET doesn’t provide any means for automatically encrypting the credentials supplied by the user, so it is up to you to implement SSL in conjunction with Forms Authentication to secure passwords against being captured in network traffic.
Tip | Always use SSL in conjunction with ASP.NET Forms Authentication to secure the transmission of user names, passwords, and during transmission between the browser and string. |
Although a default path is provided for the loginUrl, the page itself is not created by ASP.NET. Code Listing 8-4 is a simple page that takes a user name and password from the user and authenticates them. In this example, we hardcoded just one acceptable user name (TheUsername) and password (ThePassword) into our AuthenticateUser method. Once the correct credentials are received, we issue the ticket and get the user back to where she started by calling the static RedirectFromLoginPage method of the FormsAuthentication class.
Code Listing 8-4: Login.aspx
<%@Page language="C#" %>
<script runat="server">
protected void Page_Load(object o, EventArgs e) {
if(IsPostBack) {
if(AuthenticateUser(username.Text, password.Text)) {
FormsAuthentication.RedirectFromLoginPage(
"TheUsername", false);
}
else {
instructions.Text = "Please try again!";
instructions.ForeColor = System.Drawing.Color.Red;
}
}
}
bool AuthenticateUser(string username, string password) {
if((username == "TheUsername") && (password == "ThePassword")) {
return true;
}
return false;
}
</script>
<form runat="server">
<asp:Label runat="server" Text="Please input your credentials:" /><br>
Username: <asp:Textbox runat="server" /><br>
Password: <asp:Textbox runat="server"
TextMode="Password" /><br>
<asp:button runat="server" Text="LOGIN" />
</form>
The login page can be seen in Figure 8-3. With just a few lines of code, we are authenticating users. The identity of the worker process hasn’t been affected, and we didn’t have to coordinate the creation of a new Windows user account. Notice that the call to the RedirectFromLoginPage method passes false as the second parameter (the Boolean createPersistentCookie), which indicates that the authentication ticket should be a session cookie only and not a durable cookie, that is, one that persists past the time the user closes the browser.
Figure 8-3: A simple login form
Note | RedirectFromLoginPage relies on the user having been redirected to the login page with a query string to know where to redirect them back to. For example, in the URL http://www.contoso.com/login.aspx?ReturnUrl=mypage.aspx, mypage.aspx is the return URL that the user is redirected to. If the user requests the login page directly, he will be sent to the page configured as the default for the Web application in the Internet Services Manager, usually default.aspx. |
ASP.NET supports storing user names and passwords directly in the credentials element of either the web.config or machine.config file. Because storing the passwords in clear text is not a good idea, the FormsAuthentication class provides the HashPasswordForStoringInConfigFile method using a hash algorithm. There is still a downside to storing the hashed versions of passwords in the web.config file. Updating the web.config file causes the application to restart. This might be bothersome if the application is forced to restart every time a new user is created or updates his password. So you’ll probably use a back-end data store for managing Forms Authentication credentials.
You can still take advantage of the HashPasswordForStoringInConfigFile method. When adding a user, hash the password but store only the hash, not the password. To authenticate the user, hash the password again and compare the hash to what is stored. If they match, the user supplied the correct password. The odds of having two separate passwords hash to the same value is mathematically infeasible. This approach prevents anyone who has or gets access to the database from getting access to the user passwords. The hash process, for all intents and purposes, is a one-way function, meaning that you can’t get the password from the hash. You have to guess the password and hash it for confirmation, which is infeasible.
Important | Never store user passwords in clear text. |
Forms Authentication scales easily to thousands of users when working against a database backend. You can store user preferences and personal information for the user as well as additional security for use in role management, which is discussed in the next section.