Understanding Sitecore Session Timeouts

This post describes the configuration of general session timeouts in Sitecore.  Implementation teams are often interested in how to approach session management, cautious of situations where authors are logged-off after working with a piece of content for an extended amount of time (such as authoring in a RichTextField for 30+ minutes ). As I explain below, focusing on just http session timeouts will only partly address the problem. Internally, Sitecore has both regular http session timeouts and authentication timeouts that factor into this.  Some teams are tempted to trigger ajax calls to the server to extend the session lifetime . . . but as you’ll see, this is already handled by Sitecore and further customization of this process could weaken the security of the system.

For additional background: Sitecore made significant improvements to the session management logic with Sitecore 6.6 Update-7; proper support for sliding expiration was introduced, and full respect for standard ASP.Net authentication configuration was added to the platform. This may add to the confusion on this subject, as work-arounds and various custom patches may have been necessary for an older Sitecore implementation to achieve what is now out-of-the-box session support.

The Universal Editing Concern: Lost Work Scenario

Consider the following steps taken by a Sitecore author in the Content Management environment:

  1. Content Author creates new item or opens an existing one
  2. Author starts editing text in a RichText field
  3. The editing takes a long time, so the author remains working on that field for longer than the session timeout value (or they might take a 20 minute coffee brake in the middle, etc)
  4. Eventually the Content Author clicks Save to move on with their work

In a typical non-Sitecore ASP.Net application, after session expiration, all the work will be lost as the user will need to log back in to the system.  This is exactly the lost work scenario we’ll aim to avoid.

On Content Delivery Servers

For the Sitecore CD servers, one controls session timeout in the regular ASP.Net way, via the sessionState configuration node in web.config:

<sessionState timeout="180" ...

The timeout value is in minutes, so 180 equals 3 hours. Sitecore recommends a short session timeout for CD servers to conserve server resources. A default of 20 minutes is usually adequate, but each implementation is different. This has no relevance to the lost work scenario as CD servers aren’t where authors work with editing content, but I include this note in the interest of showing the complete configuration for Sitecore and session timeout management.

Content Authoring Servers

HTTP Session Timeouts
The sessionState configuration in web.config governs session duration in Sitecore CM servers just as it does for CD servers. HTTP session timeouts are defined as follows:

<sessionState timeout="180" ...

Authentication Timeouts
Along with HTTP Session timeouts, when dealing with the Sitecore Client on CM servers, it’s important to know how Authentication Timeouts come into play as these are less obvious to most implementations. To understand Authentication Timeouts, know that there are two types of Sitecore authentication sessions:
1) Not-persistent auth session
2) Persistent auth session
A “Persistent” auth session is created when the user logs in and has the “Remember Me” box checked on the login form; the “Not-Persistent” auth session is when this is not checked. See the login screen below for reference.
loginremember
The two types of auth sessions use different locations to configure timeouts. Both locations are, by default, in the web.config file of the Sitecore webroot.

Not-Persistent Authentication Session

The lifetime of the “not-persistent” auth session is determined by settings in the authentication node as follows:

<authentication mode="None">
  <forms name=".ASPXAUTH" cookieless="UseCookies" timeout="180" slidingExpiration="true" />
</authentication>

The value of the “timeout” attribute controls the lifetime of the auth session in minutes. If it’s not specified in the configuration, the default timeout value is 30 minutes. For clarity, it’s a good practice to explicitly set a value for this property.
The value of the “slidingExpiration” attribute controls whether sliding expiration is enabled.

From the MSDN documentation on slidingExpiration:
“Sliding expiration resets the expiration time for a valid authentication cookie if a request is made and more than half of the timeout interval has elapsed. If the cookie expires, the user must re-authenticate. Setting the SlidingExpiration property to false can improve the security of an application by limiting the time for which an authentication cookie is valid, based on the configured timeout value.”

Note that the slidingExpiration value defaults to true, but for clarity it’s a good practice to explicitly include it in the forms definition xml node.

Persistent Authentication Session

Lifetime of “persistent” Sitecore auth sessions is controlled by the “Authentication.ClientPersistentLoginDuration” setting; the value is in days.

<setting name="Authentication.ClientPersistentLoginDuration" value="180"/>

Note: prior to Sitecore 6.2, this setting was known as Authentication.TicketTimeout

KeepAlive.aspx

Sitecore prevents the lost work scenario, caused by regular http session expiration, via a page called “KeepAlive.aspx.” When the Content Editor is open, a short while before a session is going to expire there is Sitecore javascript code that makes a request to [webroot]/sitecore/service/keepalive.aspx to extend the session. The browser connects to the server with a simple http request to prevent session expiration.

The KeepAlive.aspx page doesn’t, however, extend the authentication expiration; it only extends the http session. This is because it can be a security vulnerability to perpetuate the lifetime of an authentication ticket automatically for an idle browsesr. The KeepAlive.aspx page can be customized to extend the authentication expiration, but it’s important to understand the repercussions. It’s possible for an editor to never have their authentication ticket expire if modifications like the following are made:

Out-of-the-box, KeepAlive.aspx uses this logic in the Page_Load event to extend the lifetime of the http session:

protected override void OnLoad(EventArgs e)
{
  if (Tracker.IsActive)
  {
    Tracker.CurrentPage.Cancel();
  }
}

To extend the authentication expiration, one could use this logic instead in KeepAlive.aspx:

protected override void OnLoad(EventArgs e)
{
  if (Tracker.IsActive)
  {
    Tracker.CurrentPage.Cancel();
  }

  //Start of customization. Not sure you really wan't to do this . . .
  HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
  if (cookie != null)
  { 
    Sitecore.Web.Authentication.TicketManager.Relogin    (Sitecore.Web.Authentication.TicketManager.GetCurrentTicketId());
  }
  //end customization
}

Again, this is not generally recommended as authors could potentially never have their authentication tickets expire when their computer is idle, but happens to still have a browser open to the Sitecore Client.

Active Directory and Authentication Session

If an implementation is using Active Directory integration (the standard Ldaplogin.aspx with the Sitecore AD Module), it’s programmatically the same as not checking the “remember me” checkbox and so it uses not-persistent auth sessions. If you’re using standard Sitecore AD integration, the authentication and forms xml nodes are most relevant to configuring authentication timeouts.

Conclusion

Session timeout and authentication session timeout are two different concepts, but often get combined together when talking about ASP.Net web application “sessions” with Sitecore.

Sitecore recommends using a session timeout (defined in the sessionState configuration) that’s as short as can be while still meeting the needs of the implementation. The default of 20 minutes is a reasonable starting point and Sitecore’s javascript calls to KeepAlive.aspx will keep that session from expiring if an author is working in the Sitecore Client but not making http requests to the web server directly due to user actions.

For the Sitecore Content Management servers, authentication session expiration is more likely to cause an author to be redirected to the login page and cause the lost work scenario. Sitecore introduces no KeepAlive functionality for authentication sessions as it could be a security vulnerability.

      There are two locations to set an authentication timeout value:

    1. The authentication node in web.config has a Forms timeout attribute (for not-persistent auth sessions, also used with standard Sitecore Active Directory module integration)
    2. The Authentication.ClientSessionTimeout setting in web.config (for persistent auth sessions)

Confusion can be caused by testing with a regular Sitecore account (not Active Directory) and one checks the “remember me” checkbox on the login page . . . then the user is testing with a persistent auth session and not exercising the configuration relevant to Sitecore’s AD module.

I should also add that there’s a session timeout bug in recent Sitecore versions; authors can be mistaken for robot traffic and so their session is terminated prematurely. It’s discussed on the Sitecore KB item https://kb.sitecore.net/articles/135940<?a> but, I’ve encountered two projects where the KB resolution wasn’t sufficient in solving the problem. In those situations, one needs to remove the suggested KB article configuration patch and modify the system.webServer section of the Sitecore web.config (if you’re using IIS Classic mode you’d use the httpModules section instead). The blue colored configuration change resolves the issue:

...<add type="Sitecore.Web.HttpModule,Sitecore.Kernel" name="SitecoreHttpModuleExtensions" />
      <add type="Sitecore.Support.FixHttpSessionTimeout.CausedByRobotDetection,Sitecore.Support.414299" name="RevertingAnalyticsBotSessionDuration" />

Armed with this knowledge, Sitecore implementations can make the best use of the session timeout settings.

GeoIP Resolution For Sitecore Explained

A Sitecore implementation can use MaxMind lookups for GeoIP resolution; this is valuable information for marketers as it provides for geography-based segmentation in reports and decision making in the Sitecore Analytics package.  The Analytics.PerformLookup setting in the /App_Config/Include/Sitecore.Analytics.config file governs the lookup activity, and is true with an OOTB installation config file (so be careful!).

It’s recommended to only set this setting to true for one server in an implementation; set this setting to false for the other servers.  For scaled (multi-server) Sitecore installations, this is a common issue since the default config file enables Analytics.PerformLookup.

You can enable lookups on either a CM or a CD instance.  The Sitecore instance should be able to access the MaxMind web service (via the public internet) in order to complete the work.  Having more than one server configured as true for this setting can cause SQL deadlocks and other problems, as well as duplicating your traffic to MaxMind (and using any lookups you’re paying for).

Under the covers, this is what this PerformLookup setting is doing:

  • Sitecore periodically starts a task on the server to perform GeoIP lookups if the setting Analytics.PerformLookup is true in Sitecore.Analytics.config
    1. This task is considered the “Lookup Worker” task
    2. The frequency of the Lookup Worker running is governed by the Analytics.PerformLookup.Interval setting in Sitecore.Analytics.config
    3. The Lookup Worker takes records in the Sitecore “Visit” table and processes any with an EmptyLocationID value in the LocationID column
      • the EmptyLocationId is a special GUID that is generated on each environment, check the first record in the Locations table with a blank business name, country, etc if you want to see what GUID your system is using
    4. The goal of the Lookup Worker is to process Visit records with an EmptyLocationID and populate them with data, so they are no longer empty.  It does this by communicating with MaxMind.

This is only part of the picture, though, as it explains how the background agent determines GeoIP  information for Visits.

What about when a page loads that makes decisions based on the visitor’s GeoIP information; for example, news sites might target different Sitecore content to European visitors compared with Asian visitors.

The process of resolving a visitor’s GeoIP information is as follows:

  1. Attempt to retrieve the GeoIP information from the memory cache
  2. If there’s no data from step 1, retrieve GeoIP information from the Analytics database
  3. If there’s no data from step 2, request GeoIP information from the MaxMind geolocation service

Each of the above steps gets progressively slower; reading from memory >  reading from the database > reading from a remote web service.

When it comes to step 3, if a request is made to MaxMind during a visitor’s HTTP request, Sitecore doesn’t make that a synchronous call and wait for a response.  I’ve seen many websites perform slowly due to blocking web service calls, so this is a smart design decision by Sitecore.  If, however, you’re in a situation where you want to wait for the GeoIP data, refer to this KB article from Sitecore for two methods of addressing it: https://kb.sitecore.net/articles/320734.

If you don’t want to pursue either work-around in the Sitecore KB article, but are using geolocation targeting in your implementation, you should plan for a graceful fallback.  Provide for a generic set of data for non-geolocation targeted visitors.

Additional references on GeoIP resolution with Sitecore include: