104 votes

Empêcher l'utilisateur de voir la page sécurisée précédemment visitée après la déconnexion

J'ai la exigence que l'utilisateur final ne devrait pas pouvoir retourner à la page restreinte après s'être déconnecté. Mais actuellement, l'utilisateur final est capable de le faire en utilisant le bouton retour du navigateur, en visitant l'historique du navigateur ou même en réentrant l'URL dans la barre d'adresse du navigateur.

Fondamentalement, je veux que l'utilisateur final ne soit pas capable d'accéder à la page restreinte de quelque manière que ce soit après s'être déconnecté. Comment puis-je réaliser cela de la meilleure façon? Est-ce que je peux désactiver le bouton retour avec JavaScript?

7 votes

Utiliser le modèle Post-request-get. Googlez-le.

142voto

BalusC Points 498232

Vous pouvez et ne devriez pas désactiver le bouton de retour du navigateur ou l'historique. C'est mauvais pour l'expérience utilisateur. Il existe des astuces JavaScript, mais elles ne sont pas fiables et ne fonctionneront pas non plus lorsque le client a désactivé JS.

Votre problème concret est que la page demandée est chargée à partir du cache du navigateur au lieu d'être directement du serveur. C'est essentiellement sans danger, mais en effet cela peut être déroutant pour l'utilisateur final, car il pense à tort que cela vient vraiment du serveur.

Il vous suffit d'instruire le navigateur de ne pas mettre en cache toutes les pages JSP restreintes (et donc pas seulement la page/action de déconnexion elle-même!). De cette façon, le navigateur est obligé de demander la page au serveur au lieu du cache et donc tous les contrôles de connexion sur le serveur seront exécutés. Vous pouvez faire cela en utilisant un Filter qui définit les en-têtes de réponse nécessaires dans la méthode doFilter() :

@WebFilter
public class NoCacheFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        response.setDateHeader("Expires", 0); // Proxies.

        chain.doFilter(req, res);
    }

    // ...
}

Associez ce Filter à un url-pattern d'intérêt, par exemple *.jsp.

@WebFilter("*.jsp")

Ou si vous souhaitez appliquer cette restriction uniquement aux pages sécurisées, vous devez spécifier un modèle d'URL qui couvre toutes ces pages sécurisées. Par exemple, s'ils sont tous dans le dossier /app, alors vous devez spécifier le modèle d'URL de /app/*.

@WebFilter("/app/*")

De plus, vous pouvez faire ce travail dans le même Filter que celui où vous vérifiez la présence de l'utilisateur connecté.

N'oubliez pas de vider le cache du navigateur avant de tester ! ;)

Voir aussi :

2 votes

Parfois ce n'est pas suffisant, je me souviens d'avoir eu ce problème. Le navigateur se souvient juste de la dernière page. Mais c'était peut-être IE6, je ne me souviens pas :)

3 votes

@Bozho: Soit vous avez fourni un ensemble incomplet d'en-têtes, soit le navigateur a encore la page en cache.

1 votes

@Chris: Cela fonctionne pour moi avec Firefox et tous les autres navigateurs. Votre problème est causé ailleurs. Peut-être avez-vous oublié de vider certains caches ? Ou ces en-têtes sont-ils définis sur de mauvaises réponses ?

5voto

Sathyan Points 28

*.jsp dans le motif d'URL ne fonctionnera pas si vous redirigez une page. Essayez d'inclure également votre servlet... cela rendra votre application sécurisée contre ce problème de bouton de retour.

2voto

user2459714 Points 41

La manière la plus simple de le faire sans désactiver le bouton de retour du navigateur est d'ajouter ce code à l'événement page_load de la page à laquelle vous ne voulez pas que l'utilisateur revienne après s'être déconnecté :

if (!IsPostBack)
    {
        if (Session["userId"] == null)
        {
            Response.Redirect("Login.aspx");
        }
        else
        {
        Response.ClearHeaders();
        Response.ClearContent();
        Response.Clear();
        Session.Abandon();
        Session.Remove("\\w+");
        Response.AddHeader("Cache-Control", "no-cache, no-store, max-age = 0, must-revalidate");
        Response.AddHeader("Pragma", "no-cache");
        Response.AddHeader("Expires", "0");
        }
    }

6 votes

Bien que votre réponse soit utile, veuillez poster la réponse qui concerne le langage de programmation du demandeur. Votre solution en C# n'aidera pas dans le projet Java EE du demandeur.

1voto

Dan Points 4105

La bonne manière de faire est d'ajouter l'en-tête

Vary: Cookie

sur les pages sécurisées. Lorsque l'utilisateur se déconnecte, effacez leur cookie de session. Ensuite, lorsqu'ils naviguent de nouveau après s'être déconnectés, le cache du navigateur sera manquant. Cela a également l'avantage de ne pas désactiver complètement la mise en cache.

0voto

Bozho Points 273663

Vous pouvez essayer de dire au navigateur de ne pas mettre en cache la page d'accueil (en utilisant les en-têtes appropriés - Expires, Cache-Control, Pragma). Mais cela n'est pas garanti de fonctionner. Ce que vous pouvez faire, c'est faire un appel ajax au serveur lors du chargement de la page pour vérifier si l'utilisateur est connecté, et si ce n'est pas le cas - rediriger.

14 votes

Mais si un esprit malveillant désactive JavaScript cela ne fonctionne pas et il verra la page quand même.

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