c.netasp.net-mvcsession-cookiesactionfilterattribute

Cookie value expiring before the cookie expires


I have an asp.net MVC app that i am working on and I wrote a custom actionfilter in order to filter out certain controller actions based on authorization levels which are set on login and stored in an encrypted cookie along side the formsauthentication cookie, both cookies are set to have the same expiration time but for some reason after awhile of idle time the authorization cookie value becomes blank, i haven't been able to debug and catch it in the act but it just disappears

my actionfilter code looks like this:

string usersRole = "";
if (filterContext.HttpContext.Session["role"] != null)
usersRole = filterContext.HttpContext.Session["role"].ToString();
else if (filterContext.HttpContext.Response.Cookies["ArisPortalCookie"].Value != null)
{
usersRole = filterContext.HttpContext.Response.Cookies["ArisPortalCookie"].Value;
filterContext.HttpContext.Session["role"] = usersRole;
}
string encryptedRole = EncryptionHelper.Encrypt(RoleToCheckFor);

if (encryptedRole == usersRole || usersRole == EncryptionHelper.Encrypt("Admin")) //if the user's role and role required match, we have success
        {
            //now we break down the response action based on what role was required
            if (RoleToCheckFor == "Admin")
            {
            }
            else if (RoleToCheckFor == "Tech" || RoleToCheckFor == "Admin")
            {

            }
            else if (RoleToCheckFor == "Physician" || RoleToCheckFor == "Admin")
            {

            }
        }
        else
        {
            filterContext.Result = new ViewResult
            {
                ViewName = "NoAuth",
                ViewData = filterContext.Controller.ViewData,
                TempData = filterContext.Controller.TempData
            };
        }

Solution

  • I do the same to store Roles. Why have them side by side?

    I assume you're doing something like this:

    FormsAuthenticationTicket authTicket =
                  new FormsAuthenticationTicket(1,
                                                username,
                                                DateTime.Now,
                                                DateTime.Now.AddMinutes(60),
                                                rememberMe,
                                                roles);
                string encTicket = FormsAuthentication.Encrypt(authTicket);
                HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
                authenticationCookie.HttpOnly = true;  
                contextBase.Response.Cookies.Add(authenticationCookie);
    

    If you are using FormsAuthentication.SetAuthCookie as well, which I don't think you need to and I don't, then make sure your config has timeout set to 60 minutes as well or equivalent to your time of above.

    Reading values (piped format) from cookie (as requested)

    private static void ReadCookieForPrincipal()
    {
        string cookieName = FormsAuthentication.FormsCookieName;
        HttpCookie authCookie = HttpContext.Current.Request.Cookies[cookieName];
    
        // If the cookie can't be found, don't issue the ticket
        if (authCookie == null) return;
    
        // Get the authentication ticket and rebuild the principal & identity
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        string[] roles = authTicket.UserData.Split(new Char[] { '|' });
        GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
        GenericPrincipal userPrincipal = new GenericPrincipal(userIdentity, roles);
        HttpContext.Current.User = userPrincipal;
    }