Question

I am having an issue with the user session timeout on a hosted MVC 4 website. When I run the site locally with IIS-Express, I have a very long timeout period. Once the site gets published to the host (GoDaddy), the timeout period for logins drops to something absurdly short (~10-15 minutes).

I am using forms authentication. On login I use the standard:

FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

Then in my controllers I am using the Authorize attribute:

[Authorize]
public class BillingAccountController : Controller { ... }

I have tried several solutions that involve changing settings in the web.config. At this point, I have lines below to extend the timeouts:

<configuration>
  ...
  <system.web>
    ...
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="2880" cookieless="UseCookies" />
    </authentication>
    ...
    <sessionState mode="InProc" cookieless="UseCookies" timeout="2880" />
  ...
  </system.web>
  ...
</configuration>

But this does not work. It almost seems like it's being ignored by the host.

I've seen some solutions that change IIS7 settings, but since this is hosted I do not think I have access to that. (I've looked into my GoDaddy dashboard, and while there is an IIS menu, it is extremely limited.)

The website has been live for about 4 months, and this is the one continual complaint from the client.

I am using a custom Role and Membership providers, if that helps. I am only using Forms Auth for creating and authorizing the auth cookies. At this point, I could be open to another login solution. Such as abandoning forms authentication if I have to.

I can imagine some work-arounds, such as creating my own cookie with a custom attribute, or some kind of periodic AJAX call which somehow extends the session, or abandoning cookies and use the database, searching for a third party solution, etc,....

The client wants me to do something where it - quote - "never" forgets. I'm not sure that's the right answer. But if I can at least make it timeout after an hour or 2 of inactivity, I think they will be happy, as this 10-15 timeout is really annoying.

The bottom line questions are: how to I extend the session/login timeout, and if I can't because of the host, what is the best way to get around it?

UPDATE

After reading up on the resources provided by @DouglasThomas in his answer, I updated the web.config to use SQLServer sessions instead:

<sessionState mode="SQLServer" sqlConnectionString="ConnSessionState" sqlCommandTimeout="30" cookieless="false" timeout="1440" />

With the connection string:

<add name="ConnSessionState" connectionString="data source=1.1.1.1,1433;user id=userid;password=**************" providerName="System.Data.SqlClient" />

This does not seemed to have fixed the issue. The user log in is still timing out in less than 20 minutes. Though, I do have a follow question: does SQLServer sessions require any configuration on the SQL database side? Or just the web.config changes? The documents I read were not clear.

UPDATE 2

By @DaveA's suggestion, I have updated my solution. But it still does not seem to be working. I have configured my SQL Server Express with the asp session state database. I used this Microsoft document as a guide to first reconfigure the server settings (a requirement for SQL Express), then I used the following command line:

aspnet_regsql.exe -ssadd -sstype p -S SERVERPC\SQLEXPRESS -E

to create the session state database in the ASPState database. The new database was successfully created with several tables and numerous stored procedures. I then updated the sessionState node in the web.config as such:

<sessionState 
  mode="SQLServer"
  sqlConnectionString="data source=1.1.1.1,1433;user id=userid;password=**************" 
  allowCustomSqlDatabase="true"
  sqlCommandTimeout="30"
  cookieless="false"
  timeout="1440"
  />

But it does not appear to have had any affect on the duration of the login. I cannot tell if it is even making the connection to the database as no new records have populated the tables in the ASPState DB. I will note that I am not explicitly using session variables anywhere in my web application. I am assuming that the Forms Authentication is supposed to be using them somehow.

Solution

After a concerted effort with @DaveA, he uncovered an article on an www.asp.net forum of someone having pretty much the same problem: http://forums.asp.net/t/1967093.aspx?Forms+authentication+session+timeout+issue+after+10+minutes

Per @DaveA's suggestion I added a machineKey section to my web.config (which I generated from here). After uploading and testing on the live website, then after over 20 hours of inactivity, the user login persisted. So I believe that the machine key was the answer in my case.

Was it helpful?

Solution

The Problem is:

You are trying to use a defined Connection String with the SessionState Provider. This is very logical, but doesn't work because SessionState Provider still uses it's original definition from ASP.NET 1.0, while Connection Strings were introduced in ASP.NET 2.0.

This is an odd inconsistency that Microsoft never addressed.

In order to setup DBSession States:

1) Use your full connection string when you define your SessionState

<sessionState mode="SQLServer" 
    sqlConnectionString="data source=1.1.1.1,1433;user id=userid;password=**************" 
    sqlCommandTimeout="30" cookieless="true" timeout="1440" />

Very Important: Set cookieless="true" and in your login method make sure that rememberme=false. These steps are important to prevent the framework from using cookies for session state.

2) Create the schema on your sql server:

aspnet_regsql.exe -ssadd -d <Your Database> 
           -sstype c -S <Server> -U <Username> -P <Password>

3) Set Machine Key property in you web.config to bind your sessions and membership to your host:

Forms Authentication across virtual directories

http://aspnetresources.com/tools/machineKey


Keep in mind:

Using Database for session is performance costly and (as you've noticed) functionally tedious with all the parameter passing. This is far from a perfect solution.

Shared accounts often cause problems for sessions due to load balancing. In such cases, you are better off turning to Cookies. Your greater problem seems to be GoDaddy shared hosting policy of limiting Sessions timeouts (Cookies and sessions) for security reasons.

If performance becomes a problem, you may want to change hosting plans.


Machine Key: is meant to bind Membership to a Domain. When Machine Key matches, membership can be shared across multiple domains. This may make a difference even without DB session (and is worth a try).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top