it-swarm.com.de

FormsAuthentication.SignOut () meldet den Benutzer nicht ab

Ich habe meinen Kopf ein bisschen zu lange dagegen geschlagen. Wie verhindere ich, dass ein Benutzer die Seiten einer Website durchsucht, nachdem er mit FormsAuthentication.SignOut abgemeldet wurde? Das würde ich erwarten:

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

Aber das tut es nicht. Wenn ich eine URL direkt eingebe, kann ich trotzdem zur Seite navigieren. Ich habe schon eine Weile keine eigene Sicherheit mehr verwendet, also vergesse ich, warum dies nicht funktioniert.

139
Jason

Benutzer können weiterhin auf Ihrer Website surfen, da Cookies beim Aufrufen von FormsAuthentication.SignOut() nicht gelöscht werden und bei jeder neuen Anforderung authentifiziert werden. In der MS-Dokumentation heißt es, dass Cookies gelöscht werden, aber nicht, Fehler? Es ist genau das gleiche mit Session.Abandon(), Cookie ist immer noch da.

Sie sollten Ihren Code folgendermaßen ä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 Namespace. MSDN-Referenz .

199
Igor Jerosimić

Mit zwei der oben genannten Postings von x64igor und Phil Haselden wurde dieses Problem gelöst:

1. x64igor gab das Beispiel für die Abmeldung:

  • Sie müssen zuerst das Authentifizierungs-Cookie und das Sitzungs-Cookie löschen, indem Sie leere Cookies in der Antwort auf die Abmeldung zurückgeben.

    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 gab das obige Beispiel an, wie das Cachen nach dem Abmelden verhindert werden kann:

  • Sie müssen den Cache auf der Clientseite über die Antwort ungültig machen.

        // 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" ); 
    }
    
20
justdan23

Klingt für mich so, als hätten Sie Ihren Berechtigungsabschnitt für web.config nicht richtig eingerichtet. Unten finden Sie ein Beispiel.

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

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

Standardmäßig speichert der Browser unter Formularauthentifizierung Seiten für den Benutzer. Wenn Sie eine URL direkt aus dem Adressfeld des Browsers auswählen oder eingeben, wird die Seite möglicherweise aus dem Cache des Browsers abgerufen, und Sie werden niemals zum Server zurückkehren, um die Authentifizierung/Autorisierung zu überprüfen. Die Lösung besteht darin, das clientseitige Caching im Page Load-Ereignis jeder Seite oder im OnLoad () Ihrer Basisseite zu verhindern:

Response.Cache.SetCacheability(HttpCacheability.NoCache);

Vielleicht möchten Sie auch anrufen:

Response.Cache.SetNoStore();
12
Phil Haselden

Ich habe auch schon früher damit gekämpft.

Hier ist eine Analogie zu dem, was gerade passiert ... Ein neuer Besucher, Joe, kommt auf die Website und meldet sich über die Anmeldeseite mit FormsAuthentication an. ASP.NET generiert eine neue Identität für Joe und gibt ihm ein Cookie. Dieser Keks ist wie der Schlüssel zum Haus, und solange Joe mit diesem Schlüssel zurückkommt, kann er das Schloss öffnen. Jeder Besucher erhält einen neuen Schlüssel und ein neues Schloss.

Wenn FormsAuthentication.SignOut() aufgerufen wird, weist das System Joe an, den Schlüssel zu verlieren. Normalerweise funktioniert das, da Joe den Schlüssel nicht mehr hat, kann er nicht hineinkommen.

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

Soweit ich weiß, kann ASP.NET nicht angewiesen werden, das Türschloss zu ändern!

Die Art und Weise, wie ich damit leben kann, besteht darin, Joes Namen in einer Sitzungsvariablen zu speichern. Wenn er sich abmeldet, verlasse ich die Sitzung, damit ich seinen Namen nicht mehr habe. Um später zu überprüfen, ob er Zutritt hat, vergleiche ich einfach seinen Identity.Name mit dem der aktuellen Sitzung. Wenn diese nicht übereinstimmen, ist er kein gültiger Besucher.

Kurz gesagt: Verlassen Sie sich für eine Website NICHT auf User.Identity.IsAuthenticated ohne auch Ihre Sitzungsvariablen zu überprüfen!

11
Glen Little

Das funktioniert bei mir

public virtual ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        foreach (var cookie in Request.Cookies.AllKeys)
        {
            Request.Cookies.Remove(cookie);
        }
        foreach (var cookie in Response.Cookies.AllKeys)
        {
            Response.Cookies.Remove(cookie);
        }
        return RedirectToAction(MVC.Home.Index());
    }
6
Korayem

Nach langem Suchen hat das endlich bei mir geklappt. Ich hoffe, es hilft.

public ActionResult LogOff()
{
    AuthenticationManager.SignOut();
    HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);
    return RedirectToAction("Index", "Home");
}

<li class="page-scroll">@Html.ActionLink("Log off", "LogOff", "Account")</li>
6

Ich habe für alle meine Seiten eine Basisklasse geschrieben und bin auf dasselbe Problem gestoßen. Ich hatte Code wie den folgenden und es hat nicht funktioniert. Durch die Ablaufverfolgung wird die Steuerung von der Anweisung RedirectToLoginPage () zur nächsten Zeile weitergeleitet, ohne umgeleitet zu werden.

if (_requiresAuthentication)
{
    if (!User.Identity.IsAuthenticated)
        FormsAuthentication.RedirectToLoginPage();

    // check authorization for restricted pages only
    if (_isRestrictedPage) AuthorizePageAndButtons();
}

Ich fand heraus, dass es zwei Lösungen gibt. Entweder zum Ändern von FormsAuthentication.RedirectToLoginPage (); sein

if (!User.Identity.IsAuthenticated)
    Response.Redirect(FormsAuthentication.LoginUrl);

ODER, um die web.config durch Hinzufügen zu ändern

<authorization>
  <deny users="?" />
</authorization>

Im zweiten Fall erreichte die Steuerung beim Verfolgen nicht die angeforderte Seite. Es wurde sofort zur Anmelde-URL umgeleitet, bevor der Haltepunkt erreicht wurde. Daher ist die SignOut () -Methode nicht das Problem, sondern die Redirect-Methode.

Ich hoffe das kann jemandem helfen

Grüße

3
Wahid Shalaly

Diese Antwort ist technisch identisch mit Khosro.Pakmanesh. Ich poste es, um zu verdeutlichen, wie sich seine Antwort von anderen Antworten in diesem Thread unterscheidet und in welchem ​​Anwendungsfall sie verwendet werden kann.

Im Allgemeinen, um eine Benutzersitzung zu löschen

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

der Benutzer wird effektiv abgemeldet. Allerdings, wenn Sie in derselben Anfrage Request.isAuthenticated Überprüfen müssen (wie es beispielsweise in einem Autorisierungsfilter häufig vorkommt), werden Sie dies feststellen

Request.isAuthenticated == true

sogar nachdem Sie HttpContext.Session.Abandon() und FormsAuthentication.SignOut() getan haben.

Das einzige was funktionierte war zu tun

AuthenticationManager.SignOut();
HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);

Das setzt effektiv Request.isAuthenticated = false.

3
seebiscuit

Der von Ihnen veröffentlichte Code sollte das Formularauthentifizierungstoken anscheinend korrekt entfernen, sodass die betreffenden Ordner/Seiten möglicherweise nicht wirklich geschützt sind.

Haben Sie bestätigt, dass der Zugriff auf die Seiten erst nach einem Login möglich ist?

Können Sie die von Ihnen verwendeten web.config-Einstellungen und den Anmeldecode veröffentlichen?

3
Abram Simon

Ich habe hier nur einige Vorschläge ausprobiert und als ich in der Lage war, den Zurück-Button des Browsers zu verwenden, schickte mich das [Authorize] -Token für dieses [ActionResult] direkt zurück zum Anmeldebildschirm, als ich auf eine Menüauswahl klickte.

Hier ist mein Logout-Code:

        FormsAuthentication.SignOut();
        Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1));
        HttpCookie cookie = HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (cookie != null)
        {
            cookie.Expires = DateTime.Now.AddDays(-1);
            Response.Cookies.Add(cookie);
        }

Obwohl die Zurück-Funktion des Browsers mich zurückbrachte und das gesicherte Menü anzeigte (daran arbeite ich noch), konnte ich nichts tun, was in der App gesichert war.

Hoffe das hilft

3
DonH

Ich habe die meisten Antworten in diesem Thread ausprobiert, kein Glück. Endete damit:

protected void btnLogout_Click(object sender, EventArgs e)
{
    FormsAuthentication.Initialize();
    var fat = new FormsAuthenticationTicket(1, "", DateTime.Now, DateTime.Now.AddMinutes(-30), false, string.Empty, FormsAuthentication.FormsCookiePath);
    Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(fat)));
    FormsAuthentication.RedirectToLoginPage();
}

Fand es hier: http://forums.asp.net/t/1306526.aspx/1

3
stoffen

Dies passierte mir, als ich in Web.config Die Eigenschaft Authentifizierung> Formulare> Pfad einstellte. Durch das Entfernen dieses Befehls wurde das Problem behoben, und ein einfaches FormsAuthentication.SignOut(); entfernte das Cookie erneut.

2
BPM

Möglicherweise melden Sie sich von einer Subdomain (1.domain.com) an und versuchen dann, sich von einer anderen Subdomain (www.domain.com) abzumelden.

1
jorsh1

Ich hatte nur das gleiche Problem, bei dem SignOut () das Ticket anscheinend nicht richtig entfernen konnte. Aber nur in einem bestimmten Fall, in dem eine andere Logik eine Umleitung verursachte. Nachdem ich diese zweite Umleitung entfernt hatte (durch eine Fehlermeldung ersetzt), verschwand das Problem.

Das Problem muss gewesen sein, dass die Seite zur falschen Zeit umgeleitet wurde und daher keine Authentifizierung ausgelöst hat.

1
Peder Skou

Ich habe jetzt ein ähnliches Problem und glaube, dass das Problem in meinem Fall sowie im Originalposter auf der Weiterleitung beruht. Standardmäßig löst Response.Redirect eine Ausnahme aus, die sofort ausgelöst wird, bis sie abgefangen und die Umleitung sofort ausgeführt wird. Ich vermute, dies verhindert, dass die geänderte Cookie-Sammlung an den Client weitergegeben wird. Wenn Sie Ihren Code ändern, um zu verwenden:

Response.Redirect("url", false);

Dies verhindert die Ausnahme und scheint zu ermöglichen, dass das Cookie ordnungsgemäß an den Client zurückgesendet wird.

1
lostatredrock

Versuchen Sie einfach, eine Sitzungsvariable zu senden, wenn Sie auf Anmelden klicken. Überprüfen Sie auf der Begrüßungsseite zunächst, ob diese Sitzung beim Laden der Seite oder im Init-Ereignis so leer ist:

if(Session["UserID"] == null || Session["UserID"] == "")
{
    Response.Redirect("Login.aspx");
}
1
Devrishi

Für mich funktioniert der folgende Ansatz. Ich denke, wenn nach der Anweisung "FormsAuthentication.SignOut ()" ein Fehler auftritt, funktioniert SingOut nicht.

public ActionResult SignOut()
    {
        if (Request.IsAuthenticated)
        {
            FormsAuthentication.SignOut();

            return Redirect("~/");
        }
        return View();
     }
1
Aji

Ich wollte einige Informationen hinzufügen, um das Problem besser zu verstehen. Mit der Formularauthentifizierung können Benutzerdaten entweder in einem Cookie oder in der Abfragezeichenfolge der URL gespeichert werden. Die von Ihrer Site unterstützte Methode kann in der Datei web.config konfiguriert werden.

Laut Microsoft :

Die SignOut-Methode entfernt die Ticketinformationen für die Formularauthentifizierung aus dem Cookie oder der URL wenn CookiesSupported falsch ist.

Zur gleichen Zeit, sie sagen :

Einer der HttpCookieMode-Werte, der angibt, ob die Anwendung für die Formularauthentifizierung ohne Cookies konfiguriert ist. The Standard ist UseDeviceProfile.

In Bezug auf UseDeviceProfile sie sagen :

Wenn die CookieMode-Eigenschaft auf UseDeviceProfile festgelegt ist, gibt die CookiesSupported-Eigenschaft true zurück, wenn der Browser für Aktuelle Anfrage unterstützt sowohl Cookies als auch das Umleiten mit Cookies; Andernfalls gibt die Eigenschaft CookiesSupported false zurück.

Je nach Browser des Benutzers kann die Standardkonfiguration dazu führen, dass CookiesSupported true ist, was bedeutet, dass die SignOut-Methode das Ticket nicht löscht vom Keks. Dies scheint nicht intuitiv zu sein und ich weiß nicht, warum es so funktioniert - ich würde erwarten, dass SignOut den Benutzer unter allen Umständen tatsächlich abmeldet.

Eine Möglichkeit, das SignOut selbst zum Laufen zu bringen, besteht darin, den Cookie-Modus in "UseCookies" (d. H. Cookies sind erforderlich) in der Datei web.config zu ändern:

<authentication mode="Forms">
  <forms loginUrl="~/Account/SignIn" cookieless="UseCookies"/>
</authentication>

Nach meinen Tests funktioniert SignOut auf Kosten Ihrer Website nun von selbst, sodass Cookies erforderlich sind, um ordnungsgemäß zu funktionieren.

0
RogerMKE

Für MVC funktioniert das für mich:

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();
            return Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name, true));
        }
0
anovo

Session.abandon () zu machen und den Cookie zu zerstören, funktioniert ziemlich gut. Ich verwende mvc3 und es sieht so aus, als ob das Problem auftritt, wenn Sie zu einer geschützten Seite gehen, sich abmelden und Ihren Browserverlauf durchgehen. Keine große Sache, aber irgendwie nervig.

Der Versuch, Links in meiner Web-App zu durchsuchen, funktioniert jedoch richtig.

Wenn Sie festlegen, dass kein Browser-Caching durchgeführt werden soll, ist dies möglicherweise der richtige Weg.

0
James

Testen/sehen Sie dieses Verhalten mit dem IE? Es ist möglich, dass IE diese Seiten aus dem Cache bereitstellt. Es ist notorisch schwierig, IE) den Cache zu leeren, und so oft sogar Wenn Sie sich abmelden und die URL einer der "gesicherten" Seiten eingeben, wird der zuvor zwischengespeicherte Inhalt angezeigt.

(Ich habe dieses Verhalten auch gesehen, wenn Sie sich als ein anderer Benutzer angemeldet haben und IE zeigt die "Willkommen" - Leiste oben auf Ihrer Seite mit dem Benutzernamen des alten Benutzers an. Heutzutage normalerweise a reload aktualisiert es, aber wenn es dauerhaft ist, könnte es immer noch ein Caching-Problem sein.)

0
Stobor