ASP.NET Push Redirect en el Tiempo de Espera de la Sesión


Estoy buscando un tutorial, entrada de blog, o algo de ayuda en la técnica detrás de los sitios web que empujan automáticamente a los usuarios (es decir, sin un postback) cuando la sesión expira. Cualquier ayuda es apreciada

Author: Michael, 2009-01-27

10 answers

Por lo general, se establece el tiempo de espera de la sesión y, además, se puede agregar un encabezado de página para redirigir automáticamente la página actual a una página donde se borra la sesión justo antes del tiempo de espera de la sesión.

De 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)));
        }
    }
}

La SessionExpireDestinationUrl debe enlazar a una página donde borre la sesión y cualquier otro dato de usuario.

Cuando el encabezado de actualización caduque, se realizará automáticamente redireccionarlos a esa página.

 26
Author: TJB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 20:03:42

Realmente no puedes "empujar" un cliente desde tu sitio web. Su sitio responderá a las solicitudes del cliente, pero eso es realmente todo.

Lo que esto significa es que necesita escribir algo del lado del cliente (Javascript) que determinará cuándo el usuario ha agotado el tiempo, probablemente comparando la hora actual con la hora más reciente que tiene en una cookie del sitio (que actualiza con la hora actual cada vez que el usuario visita una página en su sitio), y luego redirigir si la diferencia es mayor que una cierta cantidad.

(Noto que algunas personas están abogando simplemente por crear un script que reenvíe al usuario después de una cierta cantidad de tiempo en una página. Esto funcionará en el caso simple, pero si el usuario tiene dos ventanas abiertas en el sitio, y está usando una ventana mucho, y la otra ventana no tanto, la no tanto de repente redirigirá al usuario a la página de reenvío, a pesar de que el usuario ha estado en el sitio constantemente. Además, no está realmente sincronizado con cualquier sesión de mantenimiento que está haciendo en el lado del servidor. Por otro lado, es ciertamente más fácil de codificar, y si eso es lo suficientemente bueno, entonces genial!)

 10
Author: Beska,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 20:07:47

En la sección

, usa una etiqueta META refresh como esta:
<meta http-equiv="refresh" content="0000; URL=target_page.html">

Donde 0000 es el tiempo de espera de la sesión en segundos, y target_page.html la dirección de la página a la que se va a redirigir.

 6
Author: devio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 20:03:03

Usando la clase de página personalizada y Javascript también podemos lograrlo.

Cree una clase de pagebase personalizada y escriba los códigos de funcionalidad comunes en esta clase. A través de esta clase, podemos compartir las funciones comunes a otras páginas web. En esta clase necesitamos heredar el Sistema .Web.UI.Page class. Coloque el siguiente código en la clase 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);
        }
    }
}

Above La función AutoRedirect se utilizará para redirigir la página de inicio de sesión cuando la sesión caduque, usando la ventana de javascript .setInterval , Esta ventana.setInterval ejecuta una función javascript repetidamente con un retraso de tiempo específico. Aquí estamos configurando el time delay como valor de tiempo de espera de la sesión. Una vez que ha alcanzado el tiempo de expiración de la sesión, ejecuta automáticamente la función de redirección y controla la transferencia para iniciar sesión pagina.

Página original.aspx.cs

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

Página original.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>

Nota: La ventaja de usar Javascript es que puede mostrar un mensaje personalizado en el cuadro de alerta antes de la ubicación.href que tendrá perfecto sentido para el usuario. En caso de que no desee utilizar Javascript, puede elegir meta redirección también

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")));
}
 3
Author: Durai Amuthan.H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-03 06:30:35

Estoy usando MVC3 ASp.net como principiante, probé muchas soluciones para resolver mi problema de sesión (ya que estoy usando la variable de sesión en mi código, y después del tiempo de espera no tenía valores de sesión mientras lo sigo usando y solo encuentro que mi problema estaba en el archivo de configuración. el tiempo de espera entre la autenticación y SessionState debería estar muy cerca. así que mataron (vacío) al mismo tiempo / / añadir tiempo de espera 1 y 2 para la prueba.. debe ser por lo menos 29 y 30

Usé otros cómo funciona también:

A partir de:

    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();          
    }

Y:

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);
    }
}

E incluso trabajó con Ajax para resolver sesión 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);
            }
        }

    }
 2
Author: Rasha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-27 14:34:05

Simplemente copie y pegue este fragmento de código en su Web.Archivo de configuración:

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

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

Puede poner esta línea en su Sitio.Maestro :

Response.AppendHeader("Refresh", 
                      Convert.ToString((Session.Timeout * 60)) + 
                      ";URL=~/Login.aspx");
 2
Author: ersegun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-04 15:17:36

Desafortunadamente no se puede hacer. El tiempo de espera de la sesión solo ocurre en el lado del servidor y no lo detectará hasta que el usuario realice algún tipo de acción post back.

Sin embargo, lo que puede hacer es inyectar algún código de encabezado HTML o JavaScript que empujará automáticamente al usuario a una página de cierre de sesión en el mismo período de tiempo que el tiempo de espera de la sesión. Esto no garantiza una sincronización perfecta, y puede tener problemas si su usuario está haciendo algunos elementos que requieren mucho tiempo y usted no restablecer el reloj.

Normalmente agrego este código a mis eventos Page_Load para lograr esto.

' 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)
 1
Author: Dillie-O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 20:01:24

Y si utiliza el siguiente controlador de inicio de sesión, le enviará a la URL solicitada antes de iniciar sesión:

   [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
Author: Rasha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-27 14:41:37

Por supuesto que necesita usar [Authorize] sobre la clase de controlador o incluso Acción en específico.

[Authorize]
public class MailController : Controller
{
}
 1
Author: Rasha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-27 20:04:53

Bueno, esto se vuelve complicado para las solicitudes de AJAX como Zhaph - Ben Duguid señaló. Aquí estaba mi solución para hacer que esto funcione con AJAX (usando Telerik web controls pero están construidos usando ASP.NET AJAX toolkit creo).

En pocas palabras, rodé mi propia cosa de tipo de sesión de vencimiento deslizante.

En mi Sitio.Maestro, estoy actualizando una variable de sesión en CADA postback (postback o solicitud AJAX porque las solicitudes AJAX todavía inician el evento 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);
    }

Entonces en mi marcado para mi sitio.maestro, he incluido un iframe con una página ASPX Uso "detrás de las escenas" para comprobar y ver si mi vencimiento deslizante personalizado ha expirado:

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

Ahora en mi SessionExpire.página aspx, simplemente refresco la página de vez en cuando y compruebo si la marca de tiempo ha caducado y si es así, redirijo a mi cierre de sesión.página aspx que luego determina a qué página de inicio de sesión enviar al usuario de vuelta:

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);
    }
}

Muchas gracias a las personas de arriba que publicaron información, esto me llevó a mi solución y espero que ayuda a otros.

 0
Author: Chris Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-03 00:49:53