153 Stimmen

FormsAuthentication.SignOut() meldet den Benutzer nicht ab

Ich habe mir den Kopf ein bisschen zu lange daran gestoßen. Wie verhindere ich, dass ein Benutzer die Seiten einer Website durchsuchen kann, nachdem er mit FormsAuthentication.SignOut abgemeldet wurde? Ich würde erwarten, dass dies zu tun:

FormsAuthentication.SignOut();
Session.Abandon();
FormsAuthentication.RedirectToLoginPage();

Aber das ist nicht der Fall. Wenn ich eine URL direkt eingebe, kann ich die Seite trotzdem aufrufen. Ich habe schon lange nicht mehr mit der "Roll-your-own security" gearbeitet und weiß nicht mehr, warum das nicht funktioniert.

218voto

Igor Jerosimić Punkte 13405

Die Nutzer können weiterhin auf Ihrer Website surfen, da die Cookies nicht gelöscht werden, wenn Sie die FormsAuthentication.SignOut() und sie werden bei jeder neuen Anfrage authentifiziert. In der MS-Dokumentation steht, dass das Cookie gelöscht wird, aber das tun sie nicht. Es ist genau dasselbe mit Session.Abandon() ist der Keks noch da.

Sie sollten Ihren Code wie folgt ändern:

FormsAuthentication.SignOut();
Session.Abandon();

// clear authentication cookie
HttpCookie cookie1 = new HttpCookie(FormsAuthentication.FormsCookieName, "");
cookie1.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie1);

// clear session cookie (not necessary for your current problem but i would recommend you do it anyway)
SessionStateSection sessionStateSection = (SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState");
HttpCookie cookie2 = new HttpCookie(sessionStateSection.CookieName, "");
cookie2.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie2);

FormsAuthentication.RedirectToLoginPage();

HttpCookie ist in der System.Web Namensraum. MSDN-Referenz .

24voto

justdan23 Punkte 533

Die Verwendung von zwei der oben genannten Beiträge von x64igor und Phil Haselden löste das Problem:

1. x64igor gab das Beispiel für das Abmelden:

  • Sie müssen zunächst Löschen Sie das Authentifizierungs-Cookie und das Sitzungs-Cookie indem leere Cookies in der Antwort auf die Abmeldung zurückgegeben werden.

    public ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        Session.Clear();  // This may not be needed -- but can't hurt
        Session.Abandon();
    
        // Clear authentication cookie
        HttpCookie rFormsCookie = new HttpCookie( FormsAuthentication.FormsCookieName, "" );
        rFormsCookie.Expires = DateTime.Now.AddYears( -1 );
        Response.Cookies.Add( rFormsCookie );
    
        // Clear session cookie 
        HttpCookie rSessionCookie = new HttpCookie( "ASP.NET_SessionId", "" );
        rSessionCookie.Expires = DateTime.Now.AddYears( -1 );
        Response.Cookies.Add( rSessionCookie );

2. Phil Haselden hat oben ein Beispiel dafür gegeben, wie man die Zwischenspeicherung nach der Abmeldung verhindern kann:

  • Sie müssen Invalidieren des Cache auf der Client-Seite über die Antwort .

        // Invalidate the Cache on the Client Side
        Response.Cache.SetCacheability( HttpCacheability.NoCache );
        Response.Cache.SetNoStore();
    
        // Redirect to the Home Page (that should be intercepted and redirected to the Login Page first)
        return RedirectToAction( "Index", "Home" ); 
    }

20voto

jwalkerjr Punkte 1709

Klingt für mich so, als ob Sie Ihre web.config-Autorisierungssektion nicht richtig eingerichtet haben, siehe unten für ein Beispiel.

<authentication mode="Forms">
  <forms name="MyCookie" loginUrl="Login.aspx" protection="All" timeout="90" slidingExpiration="true"></forms>
</authentication>
<authorization>
  <deny users="?" />
</authorization>

14voto

Glen Little Punkte 6737

Ich habe auch schon früher damit zu kämpfen gehabt.

Hier ist eine Analogie für das, was vor sich zu gehen scheint... Ein neuer Besucher, Joe, kommt auf die Website und meldet sich über die Anmeldeseite mit FormsAuthentication an. ASP.NET erzeugt eine neue Identität für Joe und gibt ihm ein Cookie. Dieses Cookie ist wie ein Schlüssel zum Haus, und solange Joe mit diesem Schlüssel zurückkehrt, kann er das Schloss öffnen. Jeder Besucher erhält einen neuen Schlüssel und ein neues Schloss, das er benutzen kann.

Wenn FormsAuthentication.SignOut() aufgerufen wird, sagt das System Joe, dass er den Schlüssel verlieren soll. Normalerweise funktioniert dies, da Joe den Schlüssel nicht mehr hat, kann er nicht eintreten.

Wenn Joe jedoch jemals zurückkommt und tut den verlorenen Schlüssel haben, wird er wieder hereingelassen!

Soweit ich weiß, gibt es keine Möglichkeit, ASP.NET anzuweisen, das Schloss an der Tür auszutauschen!

Ich kann damit leben, wenn ich mir Joes Namen in einer Session-Variablen merke. Wenn er sich abmeldet, verlasse ich die Sitzung, so dass ich seinen Namen nicht mehr habe. Um später zu prüfen, ob er eingelassen werden darf, vergleiche ich einfach seinen Identity.Name mit dem der aktuellen Sitzung, und wenn sie nicht übereinstimmen, ist er kein gültiger Besucher.

Kurz gesagt, verlassen Sie sich bei einer Website NICHT auf User.Identity.IsAuthenticated ohne auch Ihre Session-Variablen zu überprüfen!

14voto

Phil Haselden Punkte 2666

Der Schlüssel ist hier, dass Sie sagen: "Wenn ich eine URL direkt eingebe...".

Bei der Formularauthentifizierung speichert der Browser standardmäßig die Seiten für den Benutzer. Wenn man also eine URL direkt aus dem Adressfeld des Browsers auswählt oder sie eintippt, wird die Seite möglicherweise aus dem Browser-Cache abgerufen und nie zum Server zurückgekehrt, um die Authentifizierung/Autorisierung zu überprüfen. Die Lösung für dieses Problem besteht darin, das clientseitige Caching im Page_Load-Ereignis jeder Seite oder im OnLoad() der Basisseite zu verhindern:

Response.Cache.SetCacheability(HttpCacheability.NoCache);

Sie können auch gerne anrufen:

Response.Cache.SetNoStore();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X