C# • Working With Cookies—Easy as Pie

Listing 1. You can use cookies in a Web site that stores the roles that users belong to. Rather than fetching the user roles on each request from the database, fetch the user roles only if a specific UserRoles cookie doesn't exist. Then create the UserRoles cookies and add the roles the user belongs to. Then you can simply open the UserRoles cookie, extract the roles, and add them to the roles the current user belongs to.

//************************************************
//
// Application_AuthenticateRequest Event
//
// If the client is authenticated with the 
// application, then determine which security 
// roles he/she belongs to and replace the "User"
// intrinsic with a custom IPrincipal security 
// object that permits "User.IsInRole" role checks 
// within the application
//
// Roles are cached in the browser in an in-memory 
// encrypted cookie. If the cookie doesn't exist 
// yet for this session, create it.
//
//************************************************
void Application_AuthenticateRequest(
   Object sender, EventArgs e) {
   String[] roles = null;

   if (Request.IsAuthenticated == true) {
      // Create roles cookie if it doesn't exist 
      // yet for this session.
      if ((Request.Cookies["userroles"] == null) ||

         (Request.Cookies["userroles"].Value 
            == "")) {

         // Get roles from UserRoles table, 
         // and add to cookie
         roles = UserRoles.GetUserRoles(
            User.Identity.Name);

         CreateRolesCookie(roles);

      } else {
         // Get roles from roles cookie
         FormsAuthenticationTicket ticket = 
            FormsAuthentication.Decrypt(
               Context.Request.Cookies[
                  "userroles"].Value);

         // Ensure the user logged in and the 
         // user the cookie was issued to are 
         // the same
         if (ticket.Name != 
            Context.User.Identity.Name) {

         // Get roles from UserRoles table, 
         // and add to cookie
         roles = UserRoles.GetUserRoles(
            User.Identity.Name);

         CreateRolesCookie(roles);
      } else {
         // convert the string representation 
         // of the role data into a string 
         // array
         ArrayList userRoles = 
            new ArrayList();

         foreach (String role in 
            ticket.UserData.Split( 
               new char[] {';'} )) {
               userRoles.Add(role);
         }

         roles = (String[]) 
            userRoles.ToArray(typeof(String));

      }
   }

   // Add our own custom principal to the request 
   // containing the roles in the auth ticket
   Context.User = new 
      GenericPrincipal(Context.User.Identity, 
      roles);
   }
}

//************************************************
//
// CreateRolesCookie
//
// Used to create the cookie that store the roles 
// for the current user.
//
//************************************************
private void CreateRolesCookie(string[] roles) {

   // Create a string to persist the roles
   String roleStr = "";
   foreach (String role in roles) {
      roleStr += role;
      roleStr += ";";
   }

   // Create a cookie authentication ticket.
   FormsAuthenticationTicket ticket = new 
      FormsAuthenticationTicket(
      1,                           // version
      Context.User.Identity.Name,  // user name
      DateTime.Now,                // issue time
      DateTime.Now.AddHours(1),    // expires every hour
      false,                       // don't persist cookie
      roleStr                      // roles
   );

   // Encrypt the ticket
   String cookieStr = 
      FormsAuthentication.Encrypt(ticket);

   // Send the cookie to the client
   Response.Cookies["userroles"].Value = 
      cookieStr;
   Response.Cookies["userroles"].Path = "/";
   Response.Cookies["userroles"].Expires = 
      DateTime.Now.AddMinutes(5);

}