tags:

views:

117

answers:

1

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
            };
        }
+1  A: 

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;
}
dove
mind showing how you add roles to the formsauth cookie and then retrieve those values back?
Jimmy
yes thats what im doing minus the roles tacked on the end of the cookie, how do you pull the roles data out of the formsauth cookie?
Jimmy
mind sharing your code that checks which role the user is in?
Jimmy
@Jimmy added in the reading there, writing is trivial, I've a custom authentication service that serialises list of roles to pipe delimited string, e.g. "Admin|Moderator" for two roles.
dove
@Jimmy I have an Enum of roles, which I add as a property to my customer AuthorizeAttribute, so final check is simply filterContext.HttpContext.User.IsInRole(RoleRequired.ToString()).So if user has this role then they're in. Haven't a need for intersection of roles but easy extend for that when I do need it.
dove
very cool, thanks for the help, i never really took the time to learn the genericidentity and principal stuff ive mostly just tried to do that stuff on my own
Jimmy