asp.net - Verhindern des Ablaufs der FormsAuthentication-Ablaufzeit




webforms forms-authentication (2)

Das gleitende Ablaufdatum wird vom FormsAuthentication Modul durch erneutes Ausgeben des Cookies bei Bedarf erreicht. Um das Verschieben zu verhindern, müssen Sie die Cookie-Erneuerung verhindern.

Dies kann durch einfaches Entfernen des FormsAuthentication Cookies aus der Antwort erfolgen.

Unten ist der Code hinter einem sehr einfachen Webformular. Die aspx Seite hat ein div , das die Ausgabe des Page_Load Ereignisses Page_Load .

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        testDiv.InnerHtml = "Hi, cookie is: " + HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value;
        testDiv.InnerHtml += "<br />";
        var ticket = FormsAuthentication.Decrypt( HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
        testDiv.InnerHtml += "Expires: " + ticket.Expiration.ToString("yyyy-MM-dd HH:mm:ss");

        if(Response.Cookies.AllKeys.Contains(FormsAuthentication.FormsCookieName))
            testDiv.InnerHtml += "<br />Forms auth is trying to update the cookie in this response";

    }
    protected void Page_Prerender(object sender, EventArgs e)
    {
        if (Response.Cookies.AllKeys.Contains(FormsAuthentication.FormsCookieName))
            Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
    }
}

Das Page_Prerender Ereignis entfernt das FormsAuthentication Cookie aus der Antwort, wenn es vorhanden ist, wodurch das Verschieben verhindert wird.

Ich habe dies getestet, indem ich das Timeout für die FormsAuthentication auf zwei Minuten gesetzt habe. Dann starte ich Debug und logge mich ein. Dann aktualisiere ich die betreffende Seite.

Da FormsAuthentication das Cookie erst aktualisiert, wenn die Hälfte der FormsAuthentication ist, passiert in der ersten Minute, dass die Seite dasselbe verschlüsselte Cookie und dieselbe FormsAuthentication . Nach etwas mehr als einer Minute meldet die Seite, dass FormsAuthentication versucht, das Cookie zu erneuern. Aber der Page_Prerender entfernt das Cookie, so dass es nicht gesendet wird. Nach einer weiteren Minute werden Sie zur Anmeldeseite weitergeleitet.

Das Testen derselben, aber das Entfernen der Page_Prerender Methode zeigt, dass das Cookie geändert und die Page_Prerender nach etwa einer Minute aktualisiert wird.

Ich habe eine relativ einfache WebForms-basierte Website mit der Formularauthentifizierung:

<authentication mode="Forms">
  <forms loginUrl="login.aspx" defaultUrl="secure/home.aspx" name=".AdminSite" />
</authentication>

Da dies nicht explizit erwähnt wird, ist slidingExpiration standardmäßig auf "true" gesetzt, und daher wird ein Benutzer nicht abgemeldet, solange er sich noch auf der Site slidingExpiration .

Allerdings möchte ich, dass eine bestimmte Seite die Ablaufzeit nicht erhöht. Ist dies möglich, entweder in web.config oder in Code? Die einzigen Vorschläge, die ich gesehen habe, erwähnen das Setzen von slidingExpiration auf false , was auf der slidingExpiration Seite gelten würde.

Der Authentifizierungscookie wird festgelegt mit:

FormsAuthentication.RedirectFromLoginPage(username, False)

und daher ist es nicht praktisch, das Authentifizierungs-Cookie selbst zu ändern.


Nach einigem Nachdenken habe ich von dem Versuch abgewichen, den Cookie zu ändern oder einen zweiten Cookie zu erstellen oder den Cookie durch Ändern des Session.Timeouts außer Kraft zu setzen. Ich denke, es könnte tatsächlich einfacher sein, einen Timer zu verwenden, der System.Timers verwendet. Die Methoden für den Timer können jederzeit in eine separate Klasse eingefügt werden.

using System.Timers;



public partial class MyPage:Page
{

    private System.Timers.Timer timer;

    protected void Page_Load(object sender, EventArgs e)
    {
        SetTimer();
    }
    private void SetTimer()
    {
        // Interval is set in milliseconds- set as you please.
        timer = new System.Timers.Timer(1000 * 60);

        timer.Elapsed += OnTimedEvent;
        timer.AutoReset = true;
        timer.Enabled = true;
    }

    // In this handler, stop the timer and call a method to clear all cookies.
    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        timer.Stop();
        ClearAllCookies();
    }

    // Method to clear all cookies. There may be a simpler way to do this, you are vague about your cookies, so I supplied a clear all.

    public void ClearAllCookies()
    {
        HttpCookie cookie;
        string cookieName;
        int cookieCnt = Request.Cookies.Count;
        for(int i = 0; i < cookieCnt; i++)
        {
            cookieName = Request.Cookies[i].Name;
            cookie = new HttpCookie(cookieName);
            // This causes the cookie to expire
            cookie.Expires = DateTime.Now.AddDays(-1); 
            Response.Cookies.Add(cookie);
        }

        Response.Redirect("LogIn.aspx");
    }
}

Bearbeiten

Oder verwenden Sie eine Methode, die den Benutzer protokolliert. In jedem Fall beenden Sie die Sitzung, ohne sich für die Dauer der restlichen Website mit der Authentifizierung des Benutzers herumärgern zu müssen, außer um sie zu beenden, wenn die Sitzung auf dieser bestimmten Seite abläuft.

public void ForceLogOff(){

    Session.Clear();
    Session.Abandon();
    Session.RemoveAll();

    // Do here whatever you need to do. 
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);

    Response.Redirect("LogIn.aspx");
}

Wie Sie die Sitzung beenden, bleibt Ihnen überlassen. Auf diese Weise können Sie das gleitende Ablaufproblem außer Kraft setzen und ein benutzerdefiniertes Timeout nur innerhalb einer Seite festlegen.





forms-authentication