managing timeout of session object

managing timeout of session object

Old forum URL: forums.lhotka.net/forums/t/9619.aspx


SDM10012 posted on Saturday, October 09, 2010

in my mvc2 site if a user is idle for a while the session object times out so when they are on a view and try and navigate away or perform an action I get "object not found" when it tries to authenticate against the currentPrincipal (

how to handle ??

some way to pop up a modal window when session is about to expire ... then handle gracefully if user does not respond.

thx

Steve

 

SDM10012 replied on Monday, October 11, 2010

isn't this a pretty common issue for CSLA authentication ???

a pointer to a solution will be apprecaited.

thx

 

tmg4340 replied on Tuesday, October 12, 2010

This is more than a CSLA issue - it's a web issue.  And yes, this tends to be pretty common.  Unfortunately, the stateless nature of web browsing makes this a tough nut.  The browser and web server are not in communication with each other after the page is served, so there's no way for the web server to notify the browser that the session object is about to time out.  You can build something in Javascript that either uses timers or periodically pings the server to keep the session alive, but neither is a good or reliable solution.  Add in the fact that ASP.NET can recycle the session for you at potentially unpredictable times, and there's just no good generic solution.

Generally what you see is that people check to see whether their principal still exists, and if not the user gets redirected to the login page.  I realize that means they may end up losing data, but there's no other good answer.  If the authenticated principal is gone, you really don't have a way to save the data, since you can't authenticate the user.

Another option is to go with a more durable session state - a separate state server, or a state database.  Those don't get lost on an ASP.NET process recycle, but they can still be subject to session timeouts.

Obviously, you can also increase your session timeout value.  It's not really a solution - it's basically kicking the can down the road.  But if you have users who are routinely leaving their desk mid-workflow for an extended period of time (and you can't convince them of the folly of that behavior Smile), simply giving them more time to get back to their desk may actually work.

HTH

- Scott

xAvailx replied on Wednesday, October 13, 2010

This is what I've done in the past:

In Global.asax

protected void Application_AcquireRequestState(object sender, EventArgs e) {
            if (HttpContext.Current.Handler is IRequiresSessionState) {
                if (Csla.ApplicationContext.AuthenticationType == "Windows") return;

                System.Security.Principal.IPrincipal principal;
                try {
                    principal = (System.Security.Principal.IPrincipal)HttpContext.Current.Session["CslaPrincipal"];
                }
                catch {
                    principal = null;
                }

                if (principal == null) {
                    if (User.Identity.IsAuthenticated && User.Identity is FormsIdentity) {
                        // no principal in session, but ASP.NET token still valid - so sign out ASP.NET
                        FormsAuthentication.SignOut();
                   
                        string redirectUrl = "LoginUrlHere";

                        HttpContext.Current.Response.Redirect(redirectUrl); 
                    }
                    // didn't get a principal from Session, so
                    // set it to an unauthenticted PTPrincipal
                   
                    MyLibrary.Security.MyPrincipal.Logout();
                }
                else if (principal.Identity.IsAuthenticated && !(User.Identity is FormsIdentity)) {
                    // valid principal in session, but No ASP.NET token - so reset session, sign out
                    MyLibrary.Security.MyPrincipal.Logout();
                    HttpContext.Current.Session["CslaPrincipal"] = null;
                }
                else {
                    // use the principal from Session
                    Csla.ApplicationContext.User = principal;
                }
            }
        }

The MyPrincipal.Logout() code looks like this:

public static void Logout() {
            Csla.ApplicationContext.User = new UnauthenticatedPrincipal();
        }

This work in scenarios were session times out and/or forms authentication ticket times out. So basically it keeps both of them in-sync.

HTH.

Copyright (c) Marimer LLC