Custom Roles Cookie solution always stores itself persistently?

From: Devin Carlen (dcarlenATescapia.com)
Date: 07/19/02


From: "Devin Carlen" <dcarlenATescapia.com>
Date: Thu, 18 Jul 2002 19:30:19 -0400


Hi all,

I have implemented custom roles via an sql server database with forms
authentication almost the exact same way that the Ibuyspy portal does it. In
general it works fine, however I do have one concern. When I create my
FormsAuthenticationTicket and place the roles string in it, I specifically
tell it not to persist the cookie, but I can watch my cookie folder and see
that it is persisted. Then the next time the same user logs in, it uses the
persisted cookie instead of hitting the database again. Below is my code. If
anyone can shed some light on this I'd be grateful.

In the UpdateUserRoles function, I Trace.Warn the persist value on the
ticket. It always comes up as false, as expected, but this cookie is still
persisted to the file system. Please also note that I have verified that it
is the "authroles" cookie being persisted.

Global.asax.cs:

public class Global : System.Web.HttpApplication {
    public void Application_AuthenticateRequest( object sender, EventArgs
e ) {
        if (Request.IsAuthenticated == true)
            Security.UpdateUserRoles();
    }
}

Security.cs:

public sealed class Security
{
    /* UpdateUserRoles
    * This function updates the authroles cookie which contains
    * the current roles/access levels of the user. It is updated
    * every 2 minutes to keep any changes to user security level
    * updated.
    */
    public static void UpdateUserRoles() {
        HttpContext Context = HttpContext.Current;
        string[] roles;

        // Create the roles cookie if it doesn't exist yet for this session.
        if ((Context.Request.Cookies["authroles"] == null) ||
(Context.Request.Cookies["authroles"].Value == "")) {
            Context.Trace.Warn("No Authroles");

            // Get roles from UserRoles table, and add to cookie
            string roleStr = Users.GetRoles(
Int32.Parse(Context.User.Identity.Name) );

            // 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
            Context.Response.Cookies["authroles"].Value = cookieStr;
            Context.Response.Cookies["authroles"].Path = "/";
            Context.Response.Cookies["authroles"].Expires =
DateTime.Now.AddMinutes(2);

            // Convert roles to string array to pass to Principal
            ArrayList userRoles = new ArrayList();
            foreach (string role in roleStr.Split( new char[] {';'} )) {
                userRoles.Add(role);
            }

            roles = (string[]) userRoles.ToArray(typeof(String));
        }
        else {
            Context.Trace.Warn("Decrypt Authroles");

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

            Context.Trace.Warn( "persist:" +
ticket.IsPersistent.ToString() );

            // 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);
    }
}

Many thanks!