13

I would like to auto-redirect to login page when session time outs.

In web.config file, i have the following code

<configuration>
    <system.web>
       <sessionState mode="InProc"  timeout="1"/>
    </system.web>
</configuration>

In Global.asax file-

protected void Session_End(object sender, EventArgs e)
{
    Response.Redirect("LoginPage.aspx");
}

But after time-out, i am receiving the following error:

HttpException was unhandled by user code.

Response is not available in this context.

Any clue to solve this issue?

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
s.k.paul
  • 7,099
  • 28
  • 93
  • 168
  • 2
    You should be doing this in the authentication element.. not in code. – Simon Whitehead Sep 02 '13 at 04:46
  • 1
    When you say redirect to login page when session times out, do you mean you want the browser (client) to redirect automatically triggered from the server event? If so, this will require more than just server code, something more along the lines of using SignalR hubs to trigger client javascript redirects – SteveChapman Sep 02 '13 at 04:48
  • 3
    As far as I'm aware, the `Session_End` event will not fire as part of a request. It will fire *in the background* when the timeout happens. Next time the user comes back, he will get a new session automatically since the old one has timed out. So when the `Session_End` event takes place, there is no current `Response` that could be redirected... – user1429080 Sep 02 '13 at 04:50
  • This [related question](http://stackoverflow.com/questions/11742699/auto-redirect-to-login-after-session-timeout?rq=1) might help? – SteveChapman Sep 02 '13 at 05:01

7 Answers7

10

Session_End is called when the session ends - normally 20 minutes after the last request (for example if browser is inactive or closed).
Since there is no request there is also no response.

I would recommend to do redirection in Application_AcquireRequestState if there is no active session. Remember to avoid loops by checking current url.

Edit: I'm no fan of .Nets built in authentication, Example goes in Global.asax:

    protected void Application_AcquireRequestState(object sender, EventArgs e)
    {
        try
        {
            string lcReqPath = Request.Path.ToLower();

            // Session is not stable in AcquireRequestState - Use Current.Session instead.
            System.Web.SessionState.HttpSessionState curSession = HttpContext.Current.Session;

            // If we do not have a OK Logon (remember Session["LogonOK"] = null; on logout, and set to true on logon.)
            //  and we are not already on loginpage, redirect.

            // note: on missing pages curSession is null, Test this without 'curSession == null || ' and catch exception.
            if (lcReqPath != "/loginpage.aspx" &&
                (curSession == null || curSession["LogonOK"] == null))
            {
                // Redirect nicely
                Context.Server.ClearError();
                Context.Response.AddHeader("Location", "/LoginPage.aspx");
                Context.Response.TrySkipIisCustomErrors = true;
                Context.Response.StatusCode = (int) System.Net.HttpStatusCode.Redirect;
                // End now end the current request so we dont leak.
                Context.Response.Output.Close();
                Context.Response.End();
                return;
            }
        }
        catch (Exception)
        {

            // todo: handle exceptions nicely!
        }
    }
NiKiZe
  • 1,256
  • 10
  • 26
  • Would you please provide a snippet? i am not advanced coder in asp.net. – s.k.paul Sep 02 '13 at 05:13
  • @SKPaul Added example, But you should test this properly and understand the code, and it's consequences completely before using in production! But that of course goes for any solution. – NiKiZe Sep 02 '13 at 06:09
  • There's no need to *close* the browser to (eventually) trigger a Session_End. The user just has to be inactive (not issue requests) for the timeout period. This can be because the browser was closed, the user navigated away, he took a lunch break or was busy reading the (long?) page for 20 minutes. – Hans Kesting Sep 02 '13 at 07:04
  • @HansKesting yes of course, edited. It was a example to clarify that it is impossible to issue a redirect. – NiKiZe Sep 02 '13 at 07:23
4

If you are using something like FormsAuthentication for maintaining the security of your application, then this part (that part that you are trying to do) will be done for you. If FormsAuthentication discovers that a user's session has expired it will redirect him or her back to you login page.

Second, don't rely too much on Session_End because it will never trigger if you change session provider from InProc to SQLServer or other out of process provider.

Huske
  • 9,186
  • 2
  • 36
  • 53
  • This answer is not worded correctly. FormsAuthentication and Session are separate things. You can have a valid forms auth ticket, but also have an expiring session. That said, for what's provided in terms of nothing but a redirect to the login page, you are correct that forms authentication will do the redirect. See:https://stackoverflow.com/questions/1470777/forms-authentication-timeout-vs-session-timeout – b_levitt Jun 21 '18 at 15:36
1

You can use session property IsNewSession to detect whether it is session timeout or not.

The ASP.NET HttpSessionState class has IsNewSession() method that returns true if a new session was created for this request. The key to detecting a session timeout is to also look for the ASP.NET_SessionId cookie in the request.

Definitely I too agree that we should put the below code in some so called a custom BasePage, which is used by all pages, to implement this effectively.

override protected void OnInit(EventArgs e)
  {
       base.OnInit(e);   

if (Context.Session != null)
   {
if (Session.IsNewSession)
    {

     string CookieHeader = Request.Headers["Cookie"];
     if((CookieHeader!=null) && (CookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
     {
      // redirect to any page you need to
      Response.Redirect("sessionTimeout.aspx");
     } 
   }
 }
}

check this link for more explanations if you want to put the above code in a base page class .

R.C
  • 10,417
  • 2
  • 35
  • 48
1

You should use Application_AcquireRequestState You'll find that Application_AuthenticateRequest no longer has a session context (or never had one). In my research into this I cam across this post which solved it for me. Thanks go to Waqas Raja.

asp.net: where to put code to redirect users without a session to the homepage?

Community
  • 1
  • 1
Derek R
  • 11
  • 2
0

I think you are getting "Response is not available in this context" because the user is not making a request to the server, and therefor you cannot provide it with a response. Try Server.Transfer instead.

Zerkey
  • 795
  • 1
  • 6
  • 16
  • I also tried "Server.Transfer("~/NewPage.aspx", false);". But does not work. Error "Object reference not set to an instance of an object." – s.k.paul Sep 02 '13 at 04:54
  • Well, I suppose I would implement a javascript timer set to the same length as your session timeout, and then use window.location to redirect them on timeout. Timer would refresh on page reload, like their session. As an added bonus you could warn the user when their session is about to expire. – Zerkey Sep 02 '13 at 05:13
0

The easiest way what I feel is to use Meta information and get the trick working. Consider we have a page WebPage.aspx add the below code in the the WebPage.aspx.cs file.

private void Page_Load(object sender, System.EventArgs e){      
    Response.AddHeader("Refresh",Convert.ToString((Session.Timeout * 60) + 5));      
    if(Session[“IsUserValid”].ToString()==””)              
    Server.Transfer(“Relogin.aspx”);
}

In the above code, The WebPage.aspx is refreshed after 5 seconds once the Session is expired. And in the page load the session is validated, as the session is no more valid. The page is redirected to the Re-Login page. Every post-back to the server will refresh the session and the same will be updated in the Meta information of the WebPage.aspx.

V-rund Puro-hit
  • 5,518
  • 9
  • 31
  • 50
AVS
  • 1
  • 2
-1

you can simply do the following in web.config

<configuration>
<system.web>
<sessionState mode="InProc"  timeout="1" loginurl="destinationurl"/>
</system.web>
</configuration>

Since, we can't redirect from Session_End as no response/redirect is present there.By using this you will be redirected to destinationurl when session will timeout.Hope this helps.

Surbhi
  • 7
  • 2