CS Nuggets

This blog is for addons, bugs, fixes, and issues pertaining to Community Server.

CS: BUGFIX: Invalid or stale User Cookie causes site failure

UPDATE 04/18/2007:
This fix and several others apparently didn't make it into CS 2007, but this fix as presented is compatible with CS 2007.  I will create a later post that includes all the fixes that didn't make it into CS 2007. 

I can't believe I finally found a fix for this problem.  I stumbled upon it while working on another problem.  Here's the fix:

File: CommunityServerComponents(20)/Roles.cs:

Change the following method from:

public static string[] GetUserRoleNames(string username, bool cacheable)
{
    string[] roles = null;
    string key = "UserRoleNames:" + username.ToLower();

    if (cacheable)
        roles = CSCache.Get(key) as string[];
    else
        CSCache.Remove(key);

    if (roles == null)
    {
        // there is a situation where the cookie may be using an old username, which can cause this call to fail, at this point
        // we're too deep in the call tree to do anything else, so we just need to log the exception and force the
        // user to signout since we're having problems pulling the user's roles from the database
        try
        {
            roles = MemberRoleProfileProvider.Instance().Roles.GetRolesForUser(username);

            if (cacheable)
                CSCache.Insert(key, roles, 10 * CSCache.MinuteFactor);
        }
        catch (Exception e)
        {
            CSException cse = new CSException(CSExceptionType.RoleNotFound, String.Format("Error while trying to find a role for the user '{0}'. Possible cause is a invalid client cookie or a user rename.", username), e);
            cse.Log();

            if (CSContext.Current.RawUrl != HttpContext.Current.Request.RawUrl)
            {
                FormsAuthentication.SignOut();
                HttpContext.Current.Response.Redirect(SiteUrls.Instance().Home);
            }
        }
    }

    return roles;
}

to:

public static string[] GetUserRoleNames(string username, bool cacheable)
{
    string[] roles = null;
    string key;


    // there is a situation where the cookie may be using an old username, which can cause this call to fail, at this point
    // we're too deep in the call tree to do anything else, so we just need to log the exception and force the
    // user to signout since we're having problems pulling the user's roles from the database
    try
    {
        key = "UserRoleNames:" + username.ToLower();

        if (cacheable)
            roles = CSCache.Get(key) as string[];
        else
            CSCache.Remove(key);

        if (roles == null)
        {
            roles = MemberRoleProfileProvider.Instance().Roles.GetRolesForUser(username);

            if (cacheable)
                CSCache.Insert(key, roles, 10 * CSCache.MinuteFactor);
        }
    }
    catch (Exception e)
    {
        CSException cse = new CSException(CSExceptionType.RoleNotFound, String.Format("Error while trying to find a role for the user '{0}'. Possible cause is a invalid client cookie or a user rename.", username), e);
        cse.Log();

        if (HttpContext.Current.Request.UrlReferrer.AbsolutePath != SiteUrls.Instance().Home)
        {
            FormsAuthentication.SignOut();
            HttpContext.Current.Response.Redirect(SiteUrls.Instance().Home);
        }
    }

    return roles;
}

Comments

Bill Bosacker said:

Updated the exception test as I figured out what they were trying to do, but wasn't working.  They were attempting to make sure that they didn't get stuck in an infinite loop, but the code wasn't doing that.  This isn't how an infinite loop test should be performed, but it's all we have to work with.

# December 31, 2006 5:19 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)