Link to home
Start Free TrialLog in
Avatar of Myles Cardiff
Myles CardiffFlag for United States of America

asked on

ASP.net MVC Persistent Forms Authentication and Memory Issue

Hi Experts,

I have several ASP.net MVC 4 applications on hosted servers (GoDaddy, DiscountASP). They all have a forms authentication component, and we are running into an issue where the logins do not persist, and users keep getting kicked out and have to re-login. On DiscountASP, we've traced the issue to the fact that the application is using more memory than is allowed by the host, and the application pool is getting reset. We've done everything we can to reduce the memory footprint, but still hitting limits. We have to assume this is the same with GoDaddy, because locally and on dedicated environments, it works fine, and logins persist as they are supposed to.

So my question is: When this occurs, and the app pool is reset, is there a way to keep the users sessions active, or re-log them in automatically. Maybe by storing the session data somewhere else like in the DB? It would have to be some way to keep posted data alive too. i.e. if this occurs while someone is filling out a form, and the click submit, the data they entered doesn't get lost.

Or, I'm open to any suggestion that would help us get around this. Most of these projects have very tight budget, so dedicated hosting is probably too expensive.

Thanks!
SOLUTION
Avatar of Sammy
Sammy
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Ted Bouskill
Ted Bouskill
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Tedbilly,
you don't have to take my word on this, just try it yourself.
Disable session state  in a web.config
<sessionState mode="Off" />
forms authentication still works. it has zero dependency on session state
Also, OPis using a shared hosting provider, these guys will never allow you to use a session state server without charging you a small fortune.
The real question is why the application are relying heavily on sessions?
Avatar of Myles Cardiff

ASKER

OK, so I've configured the project to use session DB, which is working fine as far as I can tell. I see the sessions populating in the ASPStateTempSessions, and the application functions as it did before, allows logins, etc. But the authentication still gets forgotten for some reason after about 10 minutes and kicks the user back to the login page.

I'm thinking that there is something more wrong here, perhaps with the method I'm logging in the users, so I'm posting the code.

Here's my web.config authentication section:
  <authentication mode="Forms">
      <forms loginUrl="~/users/login/" defaultUrl="~/pages/" name="CheckPointAuthCookie" timeout="20160" slidingExpiration="true" requireSSL="false" cookieless="AutoDetect" />
    </authentication>

Open in new window

Here's the login page code, the SiteUser object is the Entity Framework model where the user's login info is stored:
Function Login(loginUser As SiteUser, Optional Persist As Boolean = False, Optional ReturnUrl As String = "~/projects/") As ActionResult
            Dim possibleUsers = (From s As SiteUser In db.SiteUsers Where s.UserEmail = loginUser.UserEmail)
            Dim siteuser As SiteUser
            If possibleUsers.Count <> 0 Then
                siteuser = possibleUsers.First
                Dim IsLoginValid As Boolean = siteuser.ValidateCredentials(loginUser.UserEmail, loginUser.Password)
                If IsLoginValid Then
                    Dim tkt As FormsAuthenticationTicket
                    Dim cookiestr As String
                    Dim ck As HttpCookie
                    tkt = New FormsAuthenticationTicket(1, siteuser.UserID, DateTime.Now(), Now.AddDays(30), Persist, "your custom data")
                    cookiestr = FormsAuthentication.Encrypt(tkt)
                    ck = New HttpCookie(FormsAuthentication.FormsCookieName(), cookiestr)
                    ck.Expires = tkt.Expiration
                    ck.Path = FormsAuthentication.FormsCookiePath()
                    Response.Cookies.Add(ck)
                    FormsAuthentication.SetAuthCookie(siteuser.UserID, Persist)
                    Return Redirect(ReturnUrl)
                Else
                    ModelState.AddModelError("", "The username / password combination you entered is not valid.")
                    Return View()
                End If
            Else
                ModelState.AddModelError("", "The username / password combination you entered is not valid.")
                Return View()
            End If
        End Function

Open in new window

Is there something here that could be causing this. Remember this login persists forever on localhost, so I still think it's got to be something that is different on the hosted server.
OK, there are other settings in IIS that can override your session state: Losing ASP.NET Sessions

So essentially, the cookie timeout, IIS timeout and web.config session timeout all have to work together and yes it can be confusing.  The first one that times out wins.  There is a logical reason for it so that you can control global settings, per application settings and even settings per page (if you desire)
Every timeout setting that i have access to is setting to 20160.., so I got someone from GoDaddy on the phone, to no avail, they have no idea what I'm talking about. So now I'm thinking about a work-around:

There must still be some authentication information that is held in the memory, even with the session set up for DB. I did a little experiment, where I added an Ajax call in JavaScript, every 30 seconds. So now, as long as the page is open, the session stays alive indefinitely. So it has to be some setting that GoDaddy has, that I can't see or access, that's deleting sessions after a period of inactivity, independently of the session information in the DB.

So that solves the most frustrating part of my problem: the user can't lose their session in the middle of filling out a form.

So I think now, I'm going to write a function to look for the AuthCookie, and then re-log people in if they leave the site.

Thank you guys, I appreciate the help! I'm going to split the solution between you,
For others with this problem, if you have the option, I suggest not using GoDaddy if your site needs to have a persistent login. Network Solutions and DiscountASP seem not to have this limitation (although they have others that can be equally annoying). If you're stuck with GoDaddy, then keep the session alive manually via JavaScript, and add some code to your login page do detect the authentication cookie, so that can you re-log users in if they get bounced after leaving the page. That should make the user experience (somewhat) seamless.