140 votes

FormsAuthentication.SignOut () ne déconnecte pas l'utilisateur

Je me suis cassé la tête un peu trop longtemps. Comment empêcher un utilisateur de parcourir les pages d'un site après leur déconnexion à l'aide de FormsAuthentication.SignOut? Je m'attendrais à ce que cela le fasse:

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

Mais ce n'est pas le cas. Si je tape directement une URL, je peux toujours naviguer jusqu'à la page. Je n'ai pas utilisé la sécurité personnelle depuis longtemps, alors j'oublie pourquoi cela ne fonctionne pas.

205voto

Igor Jerosimić Points 4686

Les utilisateurs peuvent toujours parcourir votre site Web car les cookies ne sont pas effacés lorsque vous appelez FormsAuthentication.SignOut () et qu'ils sont authentifiés à chaque nouvelle demande. Dans la documentation MS, on dit que les cookies seront effacés mais ils ne le font pas, bogue? C'est exactement la même chose avec Session.Abandon (), le cookie est toujours là.

Vous devriez changer votre code à ceci:

 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)
HttpCookie cookie2 = new HttpCookie("ASP.NET_SessionId", "");
cookie2.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie2);

FormsAuthentication.RedirectToLoginPage();
 

21voto

justdan23 Points 125

À l'aide de deux au-dessus de l'affichage des postes par x64igor et Phil Haselden résolu ce:

1. x64igor a donné l'exemple à faire de la Déconnexion:

  • Vous devez d'abord Effacer le Cookie d'Authentification et de Session Cookie en passant à vide les cookies dans la Réponse à la Déconnexion.

    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 a donné l'exemple ci-dessus de façon à empêcher la mise en cache après déconnexion:

  • Vous avez besoin d' Invalider le Cache sur le Côté Client via la Réponse.

        // 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 Points 828

Il me semble que votre section d'autorisation web.config n'est pas configurée correctement. Voir ci-dessous pour un exemple.

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

12voto

Phil Haselden Points 1215

La clé ici est que vous dites "Si je tape une URL directement...".

Par défaut sous formes d'authentification le navigateur met en cache les pages pour l'utilisateur. Donc, choisir une URL directement depuis les navigateurs adresse de la zone de liste déroulante, ou de le taper dans la, PEUT obtenir de la page dans le cache du navigateur, et de ne jamais revenir au serveur pour vérifier l'authentification/autorisation. La solution à ce problème est d'empêcher la mise en cache côté client dans l'événement Page_Load de chaque page, ou dans le OnLoad() de votre page de base:

Response.Cache.SetCacheability(HttpCacheability.NoCache);

Vous pouvez aussi appeler:

Response.Cache.SetNoStore();

11voto

Glen Little Points 1686

J'ai lutté avec cette avant de trop.

Voici une analogie de ce qui semble être en cours... Un nouveau visiteur, Joe, qui vient sur le site et connecte via la page de connexion à l'aide de FormsAuthentication. ASP.NET génère une nouvelle identité pour Joe, et lui donne un cookie. Ce cookie est comme la clé de la maison, et aussi longtemps que Joe revient avec cette clé, il peut ouvrir la serrure. Chaque visiteur est donné une nouvelle clé et une nouvelle serrure à utiliser.

Lors de l' FormsAuthentication.SignOut() est appelé, le système dit à Joe de perdre la clé. Normalement, cela fonctionne, puisque Joe n'a plus la clé, il ne peut pas y entrer.

Toutefois, si Joe vient jamais en arrière, et n' ont que de clés perdues, il est laissé en arrière!

À partir de ce que je peux dire, il n'y a aucun moyen de savoir ASP.NET pour changer la serrure de la porte!

La façon dont je peux vivre avec ce souvenir de Joe nom dans une variable de Session. Lorsqu'il se déconnecte, j'abandonne la Session donc je n'ai pas son nom plus. Plus tard, pour vérifier si il est autorisé, j'ai simplement comparer son Identité.Nom à ce que la session en cours, et si elles ne correspondent pas, il n'est pas valide d'un visiteur.

En bref, pour un site web, ne comptez PAS sur User.Identity.IsAuthenticated sans vérification de vos variables de Session!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X