New to Telerik UI for ASP.NET AJAX? Download free 30-day trial

Session Expired Redirect / Session Refresher Using RadWindowManager and jQuery

Environment

Product Progress® Telerik® UI for ASP.NET AJAX

Description

This control solves two problems. In a custom CMS we wrote, users were losing data when their sessions were expiring during editing of a page. We wanted to be able reset the users session countdown without having to refresh the page.

The second problem is auto-redirecting a user to the login screen if they have been logged out due to session inactivity. This control displays a RadWindow confirm popup when there is 90 seconds left on a users session.

If the user does not click the prompt within 90 seconds, they are redirected to a login page. Otherwise, the user will silently have their session timer refreshed.

Solution

To implement the control, simply add it to a page whenever the user is logged in. If a user is not logged in, you can either not add the control to the page (optimal), or set it Visible = false.

LogoutTimer.ascx

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="LogoutTimer.ascx.vb" Inherits="ScreenMatter.Admin.Web.LogoutTimer" %> 
<%@ Register Namespace="Telerik.Web.UI" TagPrefix="telerik" Assembly="Telerik.Web.UI" %> 

<telerik:RadWindowManager runat="server" ID="windowManager" Behaviors="Move" style="z-index:8000"> 
    <AlertTemplate></AlertTemplate> 
    <PromptTemplate></PromptTemplate> 
    <ConfirmTemplate> 
        <div class="rwDialogPopup radconfirm"> 
            <div class="rwDialogText"> 
                You will be logged out due to inactivity soon.<br />Time until logged out: <span class="sm_logoutTimer"></span> 
            </div> 
            <div> 
                <a onclick="$find('{0}').close(true);" class="rwPopupButton" href="javascript:void(0);"> 
                    <span class="rwOuterSpan"><span class="rwInnerSpan">Stay Logged In</span></span></a> 
            </div> 
        </div> 
    </ConfirmTemplate> 
</telerik:RadWindowManager> 
function sm_timer(sessionLength, redirectUrl) { 
    var timeleft = sessionLength; 
    var prm = Sys.WebForms.PageRequestManager.getInstance(); 

    if (prm != null) { 
        prm.add_endRequest(function() { 
        timeleft = sessionLength; 
        }); 
    } 

    var modalVisible = false; 
    var displayElements = $('.sm_logoutTimer'); 

    function updateDisplay() { 
        if (displayElements != null) { 
            var m = Math.floor(timeleft / 60); 
            var s = timeleft % 60; 
            displayElements.attr('innerHTML', m.toString() + ':' + (s <= 9 ? '0' : '') + s.toString()); 
        } 
    } 

    function logout_callback(arg) { 
        $.get(location.href); 
        modalVisible = false; 
        timeleft = sessionLength; 
    } 

    function checkPrompt() { 
        if (timeleft <= 120 && !modalVisible) { 
            modalVisible = true; 
            radconfirm('', logout_callback, 280, 140); 
            displayElements = $('.sm_logoutTimer'); 
        } 
    } 

    function logout() { 
        document.location.href = redirectUrl; 
    } 

    function tick() { 
        if (timeleft <= 0) { 
            logout(); 
        } else { 
            updateDisplay(); 
            checkPrompt(); 
            setTimeout(tick, 1000); 
        } 
        timeleft--; 
    } 

    setTimeout(tick, 1000); 
} 

LogoutTimer.ascx code behind

public partial class LogoutTimer : System.Web.UI.UserControl
{
    private static int SessionDurationInSeconds = System.Web.HttpContext.Current.Session.Timeout * 60;
    private string _logoutUrl;

    /// <summary>
    /// When the user is logged out they will be redirected here.
    /// </summary>
    public string LogoutUrl
    {
        get
        {
            return _logoutUrl;
        }
        set
        {
            _logoutUrl = value;
        }
    }

    protected void Page_Load(object sender, System.EventArgs e)
    {
        string timeoutStartScript = string.Format("sm_timer({0},\"{1}\");", SessionDurationInSeconds, LogoutUrl);
        Page.ClientScript.RegisterStartupScript(typeof(LogoutTimer), "TimeoutStartScript", timeoutStartScript, true);
    }
}
Public Partial Class LogoutTimer 
    Inherits System.Web.UI.UserControl 

    Private Shared SessionDurationInSeconds As Integer = System.Web.HttpContext.Current.Session.Timeout * 60 
    Private _logoutUrl As String 

    ''' <summary> 
    ''' When the user is logged out they will be redirected here. 
    ''' </summary> 
    Public Property LogoutUrl() As String 
        Get 
            Return _logoutUrl 
        End Get 
        Set(ByVal value As String) 
            _logoutUrl = value 
        End Set 
    End Property 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
        Dim timeoutStartScript As String = String.Format("sm_timer({0},""{1}"");", SessionDurationInSeconds, LogoutUrl) 
        Page.ClientScript.RegisterStartupScript(GetType(LogoutTimer), "TimeoutStartScript", timeoutStartScript, True) 
    End Sub 
End Class 

Example implementation:

protected void OnLoad(System.EventArgs e)
{
    if (Current.User.Identity.IsAuthenticated)
    {
        Control loginControl = LoadControl("~/auth/controls/LogoutTimer.ascx");
        LoggedInPanel.Controls.Add(loginControl);
    }
}
Protected Sub OnLoad(ByVal e As System.EventArgs) 
    If Current.User.Identity.IsAuthenticated Then 
        Dim loginControl As Control = LoadControl("~/auth/controls/LogoutTimer.ascx") 
        LoggedInPanel.Controls.Add(loginControl) 
    End If 
End Sub 
In this article