会话超时时的 ASP.NET 推送重定向

发布于 2024-07-13 00:06:38 字数 65 浏览 7 评论 0原文

我正在寻找教程、博客文章或有关在会话过期时自动推送用户(即没有回发)的网站背后的技术的一些帮助。 任何帮助表示赞赏

I'm looking for a tutorial, blog entry, or some help on the technique behind websites that automatically push users (ie without a postback) when the session expires. Any help is appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

旧情别恋 2024-07-20 00:06:38

通常,您设置会话超时,并且还可以添加页眉以自动将当前页面重定向到您在会话超时之前清除会话的页面。

来自 http://aspalliance.com/1621_Implementing_a_Session_Timeout_Page_in_ASPNET.2

namespace SessionExpirePage
{
    public partial class Secure : System.Web.UI.MasterPage
    {
        public int SessionLengthMinutes
        {
            get { return Session.Timeout; }
        }
        public string SessionExpireDestinationUrl
        {
            get { return "/SessionExpired.aspx"; }
        }
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.PageHead.Controls.Add(new LiteralControl(
                String.Format("<meta http-equiv='refresh' content='{0};url={1}'>", 
                SessionLengthMinutes*60, SessionExpireDestinationUrl)));
        }
    }
}

SessionExpireDestinationUrl 应链接到您清除 SessionExpireDestinationUrl 的页面会话和任何其他用户数据。

当刷新标头过期时,它会自动将它们重定向到该页面。

Usually, you set the session timeout, and you can additionally add a page header to automatically redirect the current page to a page where you clear the session right before the session timeout.

From http://aspalliance.com/1621_Implementing_a_Session_Timeout_Page_in_ASPNET.2

namespace SessionExpirePage
{
    public partial class Secure : System.Web.UI.MasterPage
    {
        public int SessionLengthMinutes
        {
            get { return Session.Timeout; }
        }
        public string SessionExpireDestinationUrl
        {
            get { return "/SessionExpired.aspx"; }
        }
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.PageHead.Controls.Add(new LiteralControl(
                String.Format("<meta http-equiv='refresh' content='{0};url={1}'>", 
                SessionLengthMinutes*60, SessionExpireDestinationUrl)));
        }
    }
}

The SessionExpireDestinationUrl should link to a page where you clear the session and any other user data.

When the refresh header expires, it will automatically redirect them to that page.

国产ˉ祖宗 2024-07-20 00:06:38

您无法真正从您的网站“推送”客户。 您的网站将响应客户的请求,但仅此而已。

这意味着您需要编写一些客户端(Javascript)来确定用户何时超时,可能是通过将当前时间与站点 cookie 中的最近时间进行比较(您使用当前时间更新该时间)每次用户访问您网站上的页面时),然后如果差异大于一定量则重定向。

(我注意到有些人提倡创建一个脚本,该脚本将在页面上经过一定时间后转发用户。这在简单的情况下可行,但如果用户在网站上打开了两个窗口,并且正在使用一个窗口很多,而另一个窗口不多,不太多的窗口会突然将用户重定向到转发页面,即使用户一直在该网站上。此外,它并不是真正同步。另一方面,编码肯定更容易,如果这足够好,那就太好了!)

You can't really "push" a client from your website. Your site will respond to requests from the client, but that's really it.

What this means is that you need to write something client-side (Javascript) that will determine when the user has timed out, probably by comparing the current time with the most recent time they have in a site cookie (which you update with the current time each time the user visits a page on your site), and then redirect if the difference is greater than a certain amount.

(I note that some people are advocating just creating a script that will forward the user after a certain amount of time on a page. This will work in the simple case, but if the user has two windows open on the site, and is using one window a lot, and the other window not-so-much, the not-so-much one will suddenly redirect the user to the forwarding page, even though the user has been on the site constantly. Additionally, it's not really in sync with any session keeping you're doing on the server side. On the other hand, it's certainly easier to code, and if that's good enough, then great!)

但可醉心 2024-07-20 00:06:38

在中 部分,使用如下所示的 META 刷新标记:

<meta http-equiv="refresh" content="0000; URL=target_page.html">

其中 0000 是会话超时(以秒为单位),target_page.html 是要重定向到的页面的地址。

In the <HEAD> section, use a META refresh tag like this:

<meta http-equiv="refresh" content="0000; URL=target_page.html">

where 0000 is your session timeout in seconds, and target_page.html the address of the page to be redirected to.

为你拒绝所有暧昧 2024-07-20 00:06:38

使用自定义页面类和Javascript我们也可以实现它。

创建一个自定义页面基类并将常用功能代码写入该类中。 通过这个类,我们可以将常用的功能分享给其他网页。 在这个类中,我们需要继承System.Web.UI.Page类。 将以下代码放入 Pagebase 类

PageBase.cs

namespace AutoRedirect
{
    public class PageBase : System.Web.UI.Page
    {
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            AutoRedirect();
        }

        public void AutoRedirect()
        {
            int int_MilliSecondsTimeOut = (this.Session.Timeout * 60000);
            string str_Script = @"
               <script type='text/javascript'> 
                   intervalset = window.setInterval('Redirect()'," +
                       int_MilliSecondsTimeOut.ToString() + @");
                   function Redirect()
                   {
                       window.location.href='/login.aspx'; 
                   }
               </script>";

           ClientScript.RegisterClientScriptBlock(this.GetType(), "Redirect", str_Script);
        }
    }
}

上面的 AutoRedirect 函数将用于在会话过期时重定向登录页面,方法是使用 >javascript window.setInterval,这个window.setInterval以特定的时间延迟重复执行一个javascript函数。 这里我们将时间延迟配置为会话超时值。 一旦达到会话过期时间,就会自动执行重定向功能并将控制权转移到登录页面。

OriginalPage.aspx.cs

namespace appStore
{
    public partial class OriginalPage: Basepage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }     
    }
}

OriginalPage.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="OriginalPage.aspx.cs" Inherits="AutoRedirect.OriginalPage" %>

Web.config< /strong>

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

注意:
使用 Javascript 的优点是您可以在 location.href 之前的警报框中显示自定义消息,这对用户来说非常有意义。
如果您不想使用 Javascript,您也可以选择元重定向

public void AutoRedirect()
{
    this.Header.Controls.Add(new LiteralControl(
        String.Format("<meta http-equiv='refresh' content='{0};url={1}'>",
            this.Session.Timeout * 60, "login.aspx")));
}

Using Custom Page class and Javascript also we can achieve it.

Create a custom pagebase class and write the common functionality codes into this class. Through this class, we can share the common functions to other web pages. In this class we need inherit the System.Web.UI.Page class. Place the below code into Pagebase class

PageBase.cs

namespace AutoRedirect
{
    public class PageBase : System.Web.UI.Page
    {
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            AutoRedirect();
        }

        public void AutoRedirect()
        {
            int int_MilliSecondsTimeOut = (this.Session.Timeout * 60000);
            string str_Script = @"
               <script type='text/javascript'> 
                   intervalset = window.setInterval('Redirect()'," +
                       int_MilliSecondsTimeOut.ToString() + @");
                   function Redirect()
                   {
                       window.location.href='/login.aspx'; 
                   }
               </script>";

           ClientScript.RegisterClientScriptBlock(this.GetType(), "Redirect", str_Script);
        }
    }
}

Above AutoRedirect function will be used to redirect the login page when session expires, by using javascript window.setInterval, This window.setInterval executes a javascript function repeatedly with specific time delay. Here we are configuring the time delay as session timeout value. Once it’s reached the session expiration time then automatically executes the Redirect function and control transfer to login page.

OriginalPage.aspx.cs

namespace appStore
{
    public partial class OriginalPage: Basepage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }     
    }
}

OriginalPage.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="OriginalPage.aspx.cs" Inherits="AutoRedirect.OriginalPage" %>

Web.config

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

Note:
The advantage of using Javascript is you could show custom message in alert box before location.href which will make perfect sense to user.
In case if you don't want to use Javascript you could choose meta redirection also

public void AutoRedirect()
{
    this.Header.Controls.Add(new LiteralControl(
        String.Format("<meta http-equiv='refresh' content='{0};url={1}'>",
            this.Session.Timeout * 60, "login.aspx")));
}
看透却不说透 2024-07-20 00:06:38

只需复制此代码片段并将其粘贴到您的 Web.Config 文件中:

<authentication mode="Forms">
  <forms loginUrl="~/Login.aspx" slidingExpiration="true" timeout="29" />
</authentication>

<sessionState timeout="30" mode="InProc" cookieless="false" />

您可以将此行放入您的 Site.Master 中:

Response.AppendHeader("Refresh", 
                      Convert.ToString((Session.Timeout * 60)) + 
                      ";URL=~/Login.aspx");

Just copy and paste this code snippet in your Web.Config file :

<authentication mode="Forms">
  <forms loginUrl="~/Login.aspx" slidingExpiration="true" timeout="29" />
</authentication>

<sessionState timeout="30" mode="InProc" cookieless="false" />

You can put this line to your Site.Master :

Response.AppendHeader("Refresh", 
                      Convert.ToString((Session.Timeout * 60)) + 
                      ";URL=~/Login.aspx");
吃→可爱长大的 2024-07-20 00:06:38

我作为初学者使用 MVC3 ASp.net,我尝试了很多解决方案来解决我的会话问题(因为我在代码中使用 Session 变量,并且超时后我在继续使用它时没有会话值并且我只是发现我的问题出在配置文件中。身份验证和 sessionState 之间的超时应该非常接近,因此它们同时被杀死(空)//添加超时 1 和 2 进行测试..它应该至少为 29 并且30

我也使用了其他工作方式:

从 :

    protected void Session_Start(object src, EventArgs e)
    {
        if (Context.Session != null)
        {
            if (Context.Session.IsNewSession)//|| Context.Session.Count==0)
            {
                string sCookieHeader = Request.Headers["Cookie"];
                if ((null != sCookieHeader) && (sCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    //if (Request.IsAuthenticated)
                     FormsAuthentication.SignOut();
                     Response.Redirect("/Account/LogOn");
                }
            }
        }

    }

    protected void Session_End(object sender, EventArgs e)
    {
     //Code that runs when a session ends. 
     //Note: The Session_End event is raised only when the sessionstate mode 
     //is set to InProc in the Web.config file. If session mode is set to StateServer
      //or SQLServer, the event is not raised. 
        Session.Clear();          
    }

和 :

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))
                {
                    ctx.Response.Redirect("~/Home/LogOn");
                }
            }
        }

        base.OnActionExecuting(filterContext);
    }
}

开始,甚至使用 Ajax 来解决会话问题:

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (Session.Count == 0 || Session["CouncilID"] == null)
            Response.Redirect("/Account/LogOn");

        if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
        {
            filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
        }
        else
        {
            base.OnActionExecuting(filterContext);
        }
    }

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AuthorizeUserAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.Request.IsAjaxRequest())
            {//validate http request.
                if (!httpContext.Request.IsAuthenticated
                    || httpContext.Session["User"] == null)
                {
                    FormsAuthentication.SignOut();
                    httpContext.Response.Redirect("~/?returnurl=" + httpContext.Request.Url.ToString());
                    return false;
                }
            }
            return true;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult
                {
                    Data = new
                    {
                        // put whatever data you want which will be sent
                        // to the client
                        message = "sorry, but you were logged out"
                    },
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }

    }

I'm using MVC3 ASp.net as beginner, I tried many solution to solve my session problem ( since i'm using Session variable in my code, and after timeout i didn't have session values while i'm keep using it And I just find that my problem was in config file. the timeout between Authentication and sessionState should be so close. so they Killed (empty) at the same time // add timeout 1 and 2 for testing.. it's should be at least 29 and 30

I used others way it's work too :

Starting from :

    protected void Session_Start(object src, EventArgs e)
    {
        if (Context.Session != null)
        {
            if (Context.Session.IsNewSession)//|| Context.Session.Count==0)
            {
                string sCookieHeader = Request.Headers["Cookie"];
                if ((null != sCookieHeader) && (sCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    //if (Request.IsAuthenticated)
                     FormsAuthentication.SignOut();
                     Response.Redirect("/Account/LogOn");
                }
            }
        }

    }

    protected void Session_End(object sender, EventArgs e)
    {
     //Code that runs when a session ends. 
     //Note: The Session_End event is raised only when the sessionstate mode 
     //is set to InProc in the Web.config file. If session mode is set to StateServer
      //or SQLServer, the event is not raised. 
        Session.Clear();          
    }

And :

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))
                {
                    ctx.Response.Redirect("~/Home/LogOn");
                }
            }
        }

        base.OnActionExecuting(filterContext);
    }
}

And even worked with Ajax to solve session issuse:

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (Session.Count == 0 || Session["CouncilID"] == null)
            Response.Redirect("/Account/LogOn");

        if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
        {
            filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
        }
        else
        {
            base.OnActionExecuting(filterContext);
        }
    }

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AuthorizeUserAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.Request.IsAjaxRequest())
            {//validate http request.
                if (!httpContext.Request.IsAuthenticated
                    || httpContext.Session["User"] == null)
                {
                    FormsAuthentication.SignOut();
                    httpContext.Response.Redirect("~/?returnurl=" + httpContext.Request.Url.ToString());
                    return false;
                }
            }
            return true;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult
                {
                    Data = new
                    {
                        // put whatever data you want which will be sent
                        // to the client
                        message = "sorry, but you were logged out"
                    },
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }

    }
如何视而不见 2024-07-20 00:06:38

不幸的是,这是不可能的。 会话超时仅发生在服务器端,除非用户执行某种回发操作,否则您不会检测到这一点。

但是,您可以做的是注入一些 HTML 或 JavaScript 标头代码,这些代码将在会话超时的同一时间范围内自动将用户推送到注销页面。 这并不能保证完美的同步,如果您的用户正在执行一些时间密集型项目并且您没有重置时钟,您可能会遇到问题。

我通常将此代码添加到我的 Page_Load 事件中来完成此操作。

' Register Javascript timeout event to redirect to the login page after inactivity
  Page.ClientScript.RegisterStartupScript(Me.GetType, "TimeoutScript", _
                                              "setTimeout(""top.location.href = 'Login.aspx'""," & _
                                               ConfigurationManager.AppSettings("SessionTimeoutMilliseconds") & ");", True)

Unfortunately it can't be done. The session timeout only occurs on the server side and you won't detect this until the user performs some kind of post back action.

However, what you CAN do is to inject some HTML or JavaScript header code that will automatically push the user to a logout page in the same timeframe as your session timeout. This doesn't guarantee a perfect synch, and you may run into issues if your user is doing some time intensive items and you are not resetting the clock.

I typically add this code to my Page_Load events to accomplish this.

' Register Javascript timeout event to redirect to the login page after inactivity
  Page.ClientScript.RegisterStartupScript(Me.GetType, "TimeoutScript", _
                                              "setTimeout(""top.location.href = 'Login.aspx'""," & _
                                               ConfigurationManager.AppSettings("SessionTimeoutMilliseconds") & ");", True)
顾冷 2024-07-20 00:06:38

如果您使用以下登录控制器,它会在登录前将您发送到所请求的 URL:

   [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {

        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {

                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

                if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                {
                    //return Redirect(returnUrl);
                    if (!String.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                      return RedirectToAction("Index", "Home");
                    }

                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

And if you use the following Logon controller, it will send you to the requested URL before logon:

   [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {

        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {

                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

                if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                {
                    //return Redirect(returnUrl);
                    if (!String.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                      return RedirectToAction("Index", "Home");
                    }

                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }
与酒说心事 2024-07-20 00:06:38

当然,您需要在控制器类甚至具体的操作上使用 [Authorize]

[Authorize]
public class MailController : Controller
{
}

Of course you need to use [Authorize] over controller class or even Action in specific.

[Authorize]
public class MailController : Controller
{
}
青柠芒果 2024-07-20 00:06:38

正如 Zhaph - Ben Duguid 指出的那样,对于 AJAX 请求来说,这会变得很棘手。 这是我的解决方案,使其与 AJAX 一起使用(使用 Telerik Web 控件,但我相信它们是使用 ASP.NET AJAX 工具包构建的)。

简而言之,我推出了自己的滑动过期会话类型的东西。

在我的 Site.Master 中,我在每次回发(回发或 AJAX 请求,因为 AJAX 请求仍然启动 Page_Load 事件)时更新会话变量:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            if (this.Request.IsAuthenticated)
                this.pnlSessionKeepAlive.Visible = true;
            else
                this.pnlSessionKeepAlive.Visible = false;
        }

        if (this.Session["SessionStartDateTime"] != null)
            this.Session["SessionStartDateTime"] = DateTime.Now;
        else
            this.Session.Add("SessionStartDateTime", DateTime.Now);
    }

然后在我的 site.master 的标记中,我包含了一个带有 ASPX 页面的 iframe使用“幕后”来检查我的自定义滑动过期是否已过期:

<asp:Panel runat="server" ID="pnlSessionKeepAlive" Visible="false">
 <iframe id="frame1" runat="server" src="../SessionExpire.aspx" frameborder="0" width="0" height="0" / >
 </asp:Panel>

现在在我的 SessionExpire.aspx 页面中,我只是经常刷新页面并检查时间戳是否已过期,如果是,我将重定向到我的注销.aspx 页面,然后确定将用户发送回哪个登录页面:

public partial class SessionExpire : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        /* We have to do all of this because we need to redirect to 2 different login pages. The default .NET
         * implementation does not allow us to specify which page to redirect expired sessions, its a fixed value.
         */
        if (this.Session["SessionStartDateTime"] != null)
        {
            DateTime StartTime = new DateTime();
            bool IsValid = DateTime.TryParse(this.Session["SessionStartDateTime"].ToString(), out StartTime);
            if (IsValid)
            {
                int MaxSessionTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["SessionKeepAliveMins"]);
                IsValid = (DateTime.Now.Subtract(StartTime).TotalMinutes < MaxSessionTimeout);
            }

            // either their session expired or their sliding session timeout has expired. Now log them out and redirect to the correct
            // login page.
            if (!IsValid)
                this.Logout();
        }
        else
            this.Logout();

        // check every 60 seconds to see if the session has expired yet.
        Response.AddHeader("Refresh", Convert.ToString(60));
    }

    private void Logout()
    {
        this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "TimeoutScript",
                    "setTimeout(\"top.location.href = '../Public/Logout.aspx'\",\"1000\");", true);
    }
}

非常感谢上面发布信息的人,这引导我找到我的解决方案并希望它对其他人有帮助。

Well this gets tricky for AJAX requests as Zhaph - Ben Duguid pointed out. Here was my solution to make this work with AJAX (using Telerik web controls but they are built using ASP.NET AJAX toolkit I believe).

In a nutshell, I rolled my own sliding expiration session type thing.

In my Site.Master, I am updating a session variable on EVERY postback (postback or AJAX request because AJAX requests still kick off the Page_Load event):

protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            if (this.Request.IsAuthenticated)
                this.pnlSessionKeepAlive.Visible = true;
            else
                this.pnlSessionKeepAlive.Visible = false;
        }

        if (this.Session["SessionStartDateTime"] != null)
            this.Session["SessionStartDateTime"] = DateTime.Now;
        else
            this.Session.Add("SessionStartDateTime", DateTime.Now);
    }

Then in my markup for my site.master, I included an iframe with a ASPX page I use "behind the scenes" to check and see if my custom sliding expiration has expired:

<asp:Panel runat="server" ID="pnlSessionKeepAlive" Visible="false">
 <iframe id="frame1" runat="server" src="../SessionExpire.aspx" frameborder="0" width="0" height="0" / >
 </asp:Panel>

Now in my SessionExpire.aspx page, I just refresh the page every so often and check if the timestamp has lapsed and if so, I redirect to my logout.aspx page that then determines which login page to send the user back to:

public partial class SessionExpire : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        /* We have to do all of this because we need to redirect to 2 different login pages. The default .NET
         * implementation does not allow us to specify which page to redirect expired sessions, its a fixed value.
         */
        if (this.Session["SessionStartDateTime"] != null)
        {
            DateTime StartTime = new DateTime();
            bool IsValid = DateTime.TryParse(this.Session["SessionStartDateTime"].ToString(), out StartTime);
            if (IsValid)
            {
                int MaxSessionTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["SessionKeepAliveMins"]);
                IsValid = (DateTime.Now.Subtract(StartTime).TotalMinutes < MaxSessionTimeout);
            }

            // either their session expired or their sliding session timeout has expired. Now log them out and redirect to the correct
            // login page.
            if (!IsValid)
                this.Logout();
        }
        else
            this.Logout();

        // check every 60 seconds to see if the session has expired yet.
        Response.AddHeader("Refresh", Convert.ToString(60));
    }

    private void Logout()
    {
        this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "TimeoutScript",
                    "setTimeout(\"top.location.href = '../Public/Logout.aspx'\",\"1000\");", true);
    }
}

Many thanks to the people above who posted info, this lead me to my solution and hope it helps others.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文