To start with, this is code that I inherited and the person who wrote it is no longer here nor available to question.
I have users in production getting annoyed at randomly being logged out of our Asp.Net MVC application (According to references our MVC libraries are version 5). After flailing about in the code and website for a while I think I have isolated what users are seeing to the following bit of code:
public class SessionExpireFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
// check if session is supported
if (ctx.Session != null)
{
// check if a new session id was generated
if (ctx.Session.IsNewSession)
{
// If it says it is a new session, but an existing cookie exists, then it must
// have timed out
string sessionCookie = ctx.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
SessionVariables.Current.User = null;
FormsAuthentication.SignOut();
filterContext.Result = new RedirectResult("~/Account/Logon");
return;
}
}
}
base.OnActionExecuting(filterContext);
}
}
I'm not totally sure why this code is needed (why would you attribute this instead of making it global) but I have seen variations of this code around the internet in my searches but not with description of why you'd want it.
Regardless, it is already in our code base and the issues that we are having seems to be that if the user is idle in a window for a small period of time and then they do something, ctx.Session
is not null but ctx.Session.IsNewSession
is true.
This implies to me that for some reason Asp.net decided this user needed a brand new session started up for them, and since we have no idea who this user is (since all their session data is gone since ... it's a new session) we need to log them out and make them log in again.
This all seems logical except I just finally was able to hit a breakpoint inside the IsNewSession
if statement. What's odd to me is that my Session actually looks 100% filled out (and filled out correctly). This means it correctly knows who I am, and all other information that only gets put into the session when you successfully log in.
Furthermore, ctx.User.Identity.IsAuthenticated
is true, and it has the correct login name.
Everything seems to point that I have a valid session, but since this code is making the design decision that if Asp.Net creates a new session I must be logged out, the user is getting logged out.
So my question is:
Session.IsNewSession
mean in practical terms?IsNewSession
is true? As a quick side note, we are currently using Redis as our session store. Also, if relevant the application is being hosted on Azure websites (and I'm not sure how that affects session expiration).
When does a Session End? A session ends if a user has not requested or refreshed a page in the application for a specified period. By default, this is 20 minutes. If you want to set a timeout interval that is shorter or longer than the default, use the Timeout property.
In Asp, the session is cookie dependent . That is, Asp session only function when browser supports cookies. While Asp.Net supports cookieless session, so the session in Asp.Net is cookie independent .
ASP.NET MVC provides three ways (TempData, ViewData and ViewBag) to manage session, apart from that we can use session variable, hidden fields and HTML controls for the same.
The server reads the SessionId which was sent by the client in question 1. The server maintains for example a key value data object so it can load the right data for the given SessionId . ASP MVC doesn't use a viewstate since it's a completely different approach than ASP.NET.
ASP.NET creates a new Session any time a browser without a current session navigates to the site. So even if someone isn't logged in, they'll still have a Session. Likewise, if one session expires, a new session will be created the next time the browser makes a request. This new session won't have "session data" stored in it, but ctx.Session
will not be null. Also, if you have multiple servers and the load balancer happens to route the user to a different server, then that new server will try to start a new session.
Session state is tracked separately from Authentication state, meaning that one can expire while the other is still valid. For well-written applications, this typically won't cause any problems. However, some applications pre-load information into the session upon login, and treat the session as a kind of cache for this information for the length of the session. Or, they will set values on the session when the user performs certain actions, and later actions will expect those values to be on the session, because the user should have navigated through those earlier actions to get there. (e.g. a Wizard interface, where each step saves values to the session, to be used when the user clicks "Finish" on the final step.)
It's possible that your application at some point was expecting data to be on the session which wasn't there, and the developers realized it wasn't there because ASP.NET had automatically renewed the session, losing all the previously-set session data. Rather than redesigning their use of session data, they chose to make it so that any time they lose the session they'll also force the user to go back to a sane starting position, where pages won't break in weird ways just because session-stored data was lost.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With