web-dev-qa-db-fra.com

ASP.NET Push Redirect sur délai de session

Je recherche un tutoriel, une entrée de blog ou de l'aide sur la technique derrière les sites Web qui poussent automatiquement les utilisateurs (c'est-à-dire sans publication) à l'expiration de la session. Toute aide est appréciée

23
Michael

En général, vous définissez le délai d'expiration de la session et vous pouvez également ajouter un en-tête de page pour rediriger automatiquement la page en cours vers une page où vous effacez la session juste avant son expiration.

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

SessionExpireDestinationUrl doit être lié à une page où vous effacez la session et toute autre donnée utilisateur.

Lorsque l'en-tête d'actualisation expire, il les redirigera automatiquement vers cette page.

27
TJB

Vous ne pouvez pas vraiment "pousser" un client de votre site Web. Votre site répondra aux demandes du client, mais c'est tout. 

Cela signifie que vous devez écrire quelque chose côté client (Javascript) qui déterminera le délai d'expiration de l'utilisateur, probablement en comparant l'heure actuelle avec l'heure la plus récente dans un cookie de site (que vous mettez à jour avec le témoin actuel). chaque fois que l'utilisateur visite une page de votre site), puis redirige si la différence est supérieure à un certain montant. 

(Je remarque que certaines personnes recommandent simplement de créer un script qui transmettra l’utilisateur après un certain temps sur une page. Cela fonctionnera dans le cas simple, mais si l’utilisateur a deux fenêtres ouvertes sur le site et utilise Une fenêtre beaucoup, et l'autre moins, la moins grande redirigera soudainement l'utilisateur vers la page de redirection, même si l'utilisateur a été sur le site de façon constante. quelle que soit la session que vous gardez côté serveur, d’autre part, c’est certainement plus facile à coder, et si cela vous convient, c’est génial!)

10
Beska

Dans la section <HEAD>, utilisez une balise META refresh comme celle-ci:

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

où 0000 est le délai d'expiration de votre session en secondes et target_page.html l'adresse de la page à rediriger.

6
devio

En utilisant Custom Page class et Javascript, nous pouvons également y parvenir.

Créez une classe de base de page personnalisée et écrivez les codes de fonctionnalité courants dans cette classe. Grâce à cette classe, nous pouvons partager les fonctions communes avec d’autres pages Web. Dans cette classe, nous devons hériter de la classe System.Web.UI.Page. Placez le code ci-dessous dans la classe 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);
        }
    }
}

La fonction AutoRedirect ci-dessus sera utilisée pour rediriger la page de connexion à l'expiration de la session, en utilisant javascript window.setInterval, cette fenêtre.setInterval exécute une fonction javascript de manière répétée avec un délai déterminé. Ici, nous configurons le délai en tant que valeur de délai d'expiration de session. Une fois que la date d’expiration de la session a été atteinte, la fonction de redirection est automatiquement exécutée et la page de contrôle de transfert contrôlée.

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>

Remarque: L’avantage de l’utilisation de Javascript est que vous pouvez afficher un message personnalisé dans le champ d’alerte avant location.href, ce qui est tout à fait logique pour l’utilisateur . Si vous ne souhaitez pas utiliser Javascript, vous pouvez choisir la méta redirection. également

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
Durai Amuthan.H

Copiez et collez simplement cet extrait de code dans votre fichier Web.Config:

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

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

Vous pouvez mettre cette ligne sur votre Site.Master:

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

J'utilise MVC3 ASp.net en tant que débutant, j'ai essayé de nombreuses solutions pour résoudre mon problème de session (depuis que j'utilise une variable de session dans mon code, et après expiration du délai, je n'ai pas eu les valeurs de session pendant que je continue à l'utiliser. Et Je viens de trouver que mon problème était dans le fichier de configuration. Le délai d'attente entre Authentication et sessionState devrait être si proche, donc ils ont tué (vide) en même temps // ajoute le délai d'attente 1 et 2 pour les tests .. il devrait être au moins de 29 et 30 .......... 

J'ai utilisé les autres comme ça marche aussi:

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

Et :

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

Et même travaillé avec Ajax pour résoudre la 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);
            }
        }

    }
2
Rasha

Bien sûr, vous devez utiliser [Authorize] sur la classe du contrôleur ou même Action en particulier.

[Authorize]
public class MailController : Controller
{
}
1
Rasha

Et si vous utilisez le contrôleur d'ouverture de session suivant, il vous enverra à l'URL demandée avant l'ouverture de session:

   [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
Rasha

Malheureusement, cela ne peut être fait. Le délai d'expiration de la session ne se produit que du côté serveur et vous ne le détecterez pas tant que l'utilisateur n'aura pas effectué d'action de post-retour.

Cependant, vous POUVEZ faire, c'est injecter du code d'en-tête HTML ou JavaScript qui poussera automatiquement l'utilisateur vers une page de déconnexion dans le même délai que le délai d'expiration de votre session. Cela ne garantit pas une synchronisation parfaite et vous risquez de rencontrer des problèmes si votre utilisateur crée des tâches qui prennent beaucoup de temps et que vous ne réinitialisez pas l'horloge.

J'ajoute généralement ce code à mes événements Page_Load pour accomplir cela.

' 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
Dillie-O

Cela devient compliqué pour les demandes de AJAX, comme l'a souligné Zhaph - Ben Duguid. Voici ma solution pour que cela fonctionne avec AJAX (en utilisant les contrôles Web Telerik mais ils sont construits en utilisant la boîte à outils ASP.NET AJAX, je crois).

En un mot, j'ai lancé ma propre expérience de type session d'expiration glissante.

Dans mon Site.Master, je mets à jour une variable de session à CHAQUE postback (postback ou demande AJAX car les requêtes AJAX lancent toujours l'événement 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);
    }

Ensuite, dans mon balisage pour mon site.master, j'ai inclus une iframe avec une page ASPX que j'utilise "dans les coulisses" pour vérifier si ma date d'expiration personnalisée a expiré:

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

Maintenant, dans ma page SessionExpire.aspx, je viens d'actualiser la page de temps en temps et de vérifier si l'horodatage est écoulé. Si c'est le cas, je redirige vers ma page logout.aspx qui détermine ensuite la page de connexion à laquelle renvoyer l'utilisateur:

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

Un grand merci aux personnes ci-dessus qui ont posté des infos, cela m’amène à ma solution et espère que cela aidera les autres.

0
Chris Smith