Myles Cardiff
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!
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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:
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>
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
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)
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)
ASKER
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,
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,
ASKER
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.
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?