2010-01-25 3 views
5

J'ai une application MVC qui utilise [Authorize] pour protéger les bits privés. Lorsque je sélectionne l'URL SignOut(), elle me déconnecte, mais si j'appuie sur le bouton Précédent de mon navigateur, la page sécurisée me permet d'utiliser le formulaire. L'action a lieu et montre que je suis déconnecté. Le problème est qu'il effectue l'action sécurisée (insertion d'une ligne dans ma base de données). Ensuite, je peux utiliser le bouton retour et recommencer. Si j'utilise le bouton de retour après la déconnexion et que je clique sur l'actualisation du navigateur, cela signifie que je suis déconnecté et que je refuse l'accès à la page sécurisée.Utilisation du bouton de retour du navigateur après que SignOut() a autorisé l'accès à la page sécurisée (ASP.NET MVC)

Ai-je oublié quelque chose d'important? Il semble que ce pourrait être un très gros problème de sécurité.

public ActionResult LogOff(string ReturnUrl) 
{ 

    FormsAuth.SignOut(); 

    if (!String.IsNullOrEmpty(ReturnUrl)) 
    { 
     return Redirect(ReturnUrl); 
    } 
    else 
    { 

    return RedirectToAction("Index", "Page"); 
    } 
} 
+4

Avez-vous oublié d'enrouler [Authorize] autour de l'action que accepte le message (ci-dessus [AcceptVerbs (HttpVerbs.Post)]? – Langdon

+0

Non, mais quand je suis retourné à avoir un regard que je l'avais comme ceci: \t \t [AcceptVerbs (HttpVerbs.Get)] \t \t [Authorize (rôles = "Administrateur")] et \t \t [AcceptVerbs (HttpVerbs .Message)] \t \t [Autoriser (Rôles = "Administrateur")] Lorsque je mets le drapeau Autoriser avant le AcceptVerbs pour Get et Post il me laisse toujours revenir au formulaire mais il ne me laisserait pas le poster . – mark123

+0

Je voudrais toujours qu'il ne montre pas la forme sécurisée si elle permet de publier ou non. C'est un problème étrange. En utilisant la décoration [Autoriser] je ne devrais pas avoir à tester pour IsAuthenticated, devrais-je? If (! User.Identity.IsAuthenticated) \t \t \t if (! User.Identity.IsAuthenticated) {return RedirectToAction ("LogOn", "Compte");} – mark123

Répondre

5

Je pense que le problème est que le navigateur met en cache la page. C'est pourquoi il ne recharge pas la page après avoir cliqué sur le bouton de retour. Si vous spécifiez dans les en-têtes que la page ne doit pas être mise en cache, elle doit recharger la page après avoir appuyé sur le bouton Précédent. Et puis l'utilisateur est refusé. Toutefois, pour que cela fonctionne, il peut être difficile dans certains cas. Voir ce Caching Tutorial pour plus d'informations.

1

Utilisez-vous des informations de session? FormsAuth.SignOut() affecte uniquement les nouvelles instances d'une page. Quand vous êtes retourné, vous étiez autorisé à être là (précédemment). Le PostBack est autorisé, sauf si vous avez vérifié le code pour le cookie/session/authenticité de la demande. Il contourne même le global.asax car ViewState est déjà généré. Vous voudrez peut-être ajouter une instruction de suppression de session ou fournir des vérifications d'authentification supplémentaires dans vos classes de base pour vous assurer qu'un utilisateur est vraiment autorisé à être où il se trouve, QUAND ils le sont.

Alternativement, vous pouvez désactiver la mise en cache des pages, ce qui devrait rendre le bouton de retour assez inutile (la page par défaut expirera). Cela créera de l'étrangeté pour les utilisateurs qui comptent sur le bouton de retour, mais cela aidera à garantir la sécurité de la page, car cela forcera un "rendu" de la page en premier lieu.

+0

Il utilise MVC, donc les postbacks et viewstates ne devraient pas poser de problème. Utiliser 'Session.Abandon()' sur le contrôle de déconnexion est une bonne idée, cependant. –

+0

Je n'utilise pas les informations de session dans ce cas. – mark123

3

Effacement de la session peut aider. voici ma méthode de déconnexion:

public ActionResult Signout() 
    { 
     Session.Clear(); 
     FormsAuthentication.SignOut(); 
     return RedirectToAction("Index", "Home"); 
    } 
1

est de réponse tardive mais j'espère aider toute personne dans un temps à Global.asax ajouter cette méthode

protected void Application_BeginRequest() 
{ 
    Response.Cache.SetCacheability(HttpCacheability.NoCache); 
    Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1)); 
    Response.Cache.SetNoStore(); 
} 

puis après l'action principale ajouter cette vérification

if (Request.IsAuthenticated) 
{ 
    // do something 
} 
else 
{ 
    return RedirectToAction("LoginPage", "ControllerName"); 
} 

(action principale signifie toute action [httpget]) et cela fonctionnera grandement j'espère aider

Questions connexes