ASP.NET Push Redirect по истечении времени ожидания сеанса - PullRequest
23 голосов
/ 27 января 2009

Я ищу учебник, запись в блоге или некоторую помощь по технике, которая стоит за веб-сайтами, которые автоматически выдвигают пользователей (т.е. без обратной передачи), когда сеанс заканчивается. Любая помощь приветствуется

Ответы [ 10 ]

27 голосов
/ 27 января 2009

Обычно вы устанавливаете время ожидания сеанса и можете дополнительно добавить заголовок страницы, чтобы автоматически перенаправить текущую страницу на страницу, где вы очищаете сеанс непосредственно перед временем ожидания сеанса.

С 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 должен ссылаться на страницу, где вы очищаете сеанс и любые другие пользовательские данные.

Когда срок действия заголовка обновления истекает, он автоматически перенаправляет их на эту страницу.

10 голосов
/ 27 января 2009

Вы не можете «оттолкнуть» клиента со своего сайта. Ваш сайт будет отвечать на запросы клиента, но это действительно так.

Это означает, что вам нужно написать что-то на стороне клиента (Javascript), которое будет определять, когда у пользователя истек тайм-аут, возможно, сравнивая текущее время с самым последним временем, которое они имеют в файле cookie сайта (который вы обновляете с текущим временем каждый раз, когда пользователь посещает страницу на вашем сайте), а затем перенаправить, если разница превышает определенную сумму.

(Я отмечаю, что некоторые люди выступают за создание сценария, который будет пересылать пользователя через определенное время на странице. Это будет работать в простом случае, но если у пользователя есть два открытых окна на сайте, и много использует одно окно, а другое не так уж и много, но не так много, оно внезапно перенаправит пользователя на страницу пересылки, даже если пользователь постоянно находится на сайте. действительно синхронизирован с любым сеансом, который вы выполняете на стороне сервера. С другой стороны, это, безусловно, проще для кодирования, и если это достаточно хорошо, то отлично!)

6 голосов
/ 27 января 2009

В разделе используйте тег обновления META следующим образом:

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

где 0000 - время ожидания вашего сеанса в секундах, а target_page.html - адрес страницы, на которую нужно перенаправить.

3 голосов
/ 21 февраля 2014

Используя класс Custom Page и 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);
        }
    }
}

Выше Функция автоматического перенаправления будет использоваться для перенаправления страницы входа в систему по истечении сеанса, используя 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

<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")));
}
2 голосов
/ 27 апреля 2012

Я использую 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);
            }
        }

    }
2 голосов
/ 18 января 2012

Просто скопируйте и вставьте этот фрагмент кода в файл Web.Config:

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

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

Вы можете поместить эту строку на свой сайт. Мастер:

Response.AppendHeader("Refresh", 
                      Convert.ToString((Session.Timeout * 60)) + 
                      ";URL=~/Login.aspx");
1 голос
/ 27 апреля 2012

И если вы используете следующий контроллер входа в систему, он отправит вам на запрошенный 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);
    }
1 голос
/ 27 апреля 2012

Конечно, вам нужно использовать [Authorize] над классом контроллера или даже определенное действие.

[Authorize]
public class MailController : Controller
{
}
1 голос
/ 27 января 2009

К сожалению, это не может быть сделано. Тайм-аут сеанса происходит только на стороне сервера, и вы не обнаружите его, пока пользователь не выполнит какое-либо действие обратной отправки.

Однако, что вы МОЖЕТЕ сделать, это ввести код заголовка 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)
0 голосов
/ 03 мая 2011

Что ж, это сложно для запросов AJAX, как заметил Жаф, - Бен Дугид. Вот мое решение, чтобы заставить это работать с AJAX (используя веб-элементы управления Telerik, но я думаю, что они построены с использованием набора инструментов 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 я включил iframe со страницей ASPX, которую я использую «за кулисами», чтобы проверить, не истек ли мой пользовательский скользящий срок действия:

<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 я просто обновляю страницу время от времени и проверяю, истекла ли временная метка, и если да, я перенаправляю на свою страницу logout.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);
    }
}

Большое спасибо вышеупомянутым людям, которые разместили информацию, это привело меня к моему решению и надеюсь, что оно поможет другим.

...