Tuesday, February 22, 2005

ASP.NET Session Cookies and Authentication Cookies

In previous blog I briefly mentioned the Session cookie and the Authentication Cookie. How do they work?

First let's look at the Session in ASP.NET. ASP.NET Session is a state management mechanism that maintains session data inside the server for a unique user interacting with the server for a period of time. For example, you can pull a user profile data from database during user's first visit and store it into Session, then for the next requests from the same user you can retrieve the profile data directly from Session without bothering database:

User currentUser = Session["UserProfile"] as User;
if (currentUser == null)
{

currentUser = UserService.GetUserById(id);
Session[
"UserProfile"] = currentUser;
}


The Session data are stored in memory by default. But you have option to store Session data in a dedicated machine, in database, or use your you own session provider. This is important in a web farm environment.

How do ASP.NET web server identify a user and retrieve its Session data? ASP.NET uses a 120 bit identifier (Session ID) to track each session. When the user first talks to the server, the Session cookie is empty and the server will create a new Session ID and set to Session cookie which will be kept in user's browser store (non-persistent cookie). When the user talks the server again, ASP.NET looks on to Session ID and retrieves corresponding data. You can see the Session cookie using a traffic monitor tool such as Fiddler :

Cookie: ASP.NET_SessionId=ezdpwa55i5xo41rbp5bfbv55;

Now let's discuss the Authentication and Authentication cookie. Authentication is a mechanism to obtain a user's identity by validating its credential against the authority such as Active Directory or LDAP. By default ASP.NET supports Windows Authentication, Passpart Authentication, and Forms Authentication. In short, Windows Authentication is managed by IIS, Passport Authentication is handled by a web-based and centralized store control by Microsoft, and Forms Authentication is the only one that is able to check user credentials stored in a file or in a custom database. Authentication cookie is used in all three scenarios, but we only cover Forms Authentication cookie here.

With Forms Authentication, usually you create a login form with the logic to validate a user against credential store. If authentication fails then the user will be treated as anonymous user and granted limited permssion. If authentication succeeds, the server will create a Forms Authentication ticket and add the ticket in Authenticaiton cookie. This is usually done by:

FormsAuthentication.SetAuthCookie(userName, false);

Or

FormsAuthentication.RedirectFromLoginPage(userName, false);


The second parameter in above two methods sets the Authentication cookie to be non-persistent or persistent.

For security consideration, the Forms Authentication ticket is encrypted and signed using server's Machine.config configuration before saving to Authentication cookie. The default encryption algorithm is 3DES. You will see the real Authentication cookie like:

Cookie: .ASPXAUTH=5D49D0CFCC287EE624F53A0FFC51F436C098E90D6345ACC06BF249661725E004E403880ACEA9F069A221C2D4893D5BBDDA2AFE4A63D17DC04;


Because different machines have different encryption/decryption keys, the same Authentication cookie won't be able to be decrypted in all machines inside a web farm. To resolve this problem, you have to explicitly specify the values for "validationKey" and "decryptionKey" attributes in the section of your application’s web.config file in each machine cross the web farm, so all machines will use the same encryption/decryption keys.

(2006/03 updated) The same encryption/decryption keys are used to handled the ViewState for ASP.NET pages. You have to do the same configuration update if you have a web farm, otherwise you will get a server error: