Estoy mostrando datos MUY sensibles. Después de que el usuario cierra la sesión de mi servidor no quiero que otro usuario pueda ver los datos de golpear el botón Atrás del navegador.

¿Cómo puedo lograr esto?

InformationsquelleAutor Tony | 2012-04-24

2 Comentarios

  1. 77

    De forma predeterminada, el botón atrás del navegador no envía una petición HTTP al servidor de todos. En lugar de ello, se recupera la página de la caché del navegador. Esto es esencialmente inofensiva, pero de hecho confuso para el usuario final, debido a que erróneamente piensan que lo que realmente viene desde el servidor.

    Todo lo que necesitas hacer es indicar al navegador para que no la caché de las páginas restringidas. Usted puede hacer esto con un simple filtro de servlets que establece el respuesta adecuada encabezados:

    @WebFilter
    public class NoCacheFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
    
            if (!request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { //Skip JSF resources (CSS/JS/Images/etc)
                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);
        }
    
        //...
    }

    (tenga en cuenta que este filtro salta JSF las solicitudes de recursos, cuyo caché realmente necesita ser configurado por separado)

    Para conseguir que se ejecute en cada petición de JSF, establece la siguiente anotación en la clase de filtro, suponiendo que el valor de la <servlet-name> de la FacesServlet en su webapp del web.xml es facesServlet:

    @WebFilter(servletNames={"facesServlet"})

    O, para conseguir que se ejecute en un determinado patrón de URL, como la coincidencia de las páginas restringidas, por ejemplo,/app/*, /private/*, /secured/*, o por lo tanto, establece la siguiente anotación en la clase de filtro:

    @WebFilter("/app/*")

    Incluso se podría hacer el mismo trabajo en un filtro que controla el usuario que ha iniciado sesión, si usted ya tiene uno.

    Si quieres pasar a utilizar JSF utilidad de la biblioteca OmniFaces, entonces también se puede simplemente tomar su CacheControlFilter. Esto también forma transparente toma de JSF en cuenta los recursos.

    Véase también:

    • He intentado hacer esto – y cuando lo ejecuto en el depurador se detiene en el interior de la noCacheFilter: método doFilter sobre la carga de la página. Luego, cuando hago clic en el botón atrás en Firefox (pruebas localmente) de nuevo se ejecuta a través de la función. Sin embargo, termina mostrando la página anterior. ¿Qué debo buscar ?
    • El otro error que ocurre en Firefox es que cada tercera vez que haga clic en en la parte de Atrás se le dice que la página ha caducado. Cuando, a continuación, haga clic en o el botón de recarga (proporcionado por la página de error) se carga la página anterior de todos modos.
    • Sé que este tipo de vieja pregunta, sin embargo, esto no funciona para Chrome. Todavía se podía ver de campo de formulario valores introducidos cuando se hace clic en chrome.
    • eso es sólo el navegador función autocompletar, que es un problema totalmente diferente. La respuesta sin duda funciona para Chrome, uno no será capaz de acceder a páginas restringidas ya a través de botón atrás. Pruebe la reformulación de la consulta de búsqueda con el fin de encontrar las respuestas correctas.
    • en mi situación, tengo un formulario con jsf campos de entrada(no ajaxed), y he añadido por encima de filtro, después de llenar el formulario en chrome, he hecho clic diferente de la URL y hacer clic en botón atrás del navegador. Pude ver algunos campos todavía tienen valores (no todos), cuando me registre en dev tools, pude ver, caché del navegador no está disponible en lugar de eso intenta llegar desde el servidor. Pero la respuesta del servidor no tiene los valores que he añadido a esos campos. Así que creo que chrome está tratando de ser inteligente aquí por la caché de los campos de formulario de algunos hwere. Sin embargo, esto no ocurre en firefox o IE. Y mi comentario no fue para ofender a usted,
    • la palabra clave que estamos buscando es el «autocompletar». Ver también.o. stackoverflow.com/q/9930900
    • no debería la «respuesta» objeto de ser transmitido en cadena.doFilter(req, res) en lugar de «res» ? porque no trabajo para mí, ni idea de por qué no.
    • ambos se refieren exactamente el mismo objeto. Es Java, un lenguaje OO, no de PHP orso. Si no funciona para usted, entonces cualquiera de los encabezados están siendo anuladas en un momento posterior, o viejas páginas todavía están en la memoria caché del navegador, o simplemente misobserved el comportamiento del botón de retroceso (es decir, realmente golpeó el servidor, pero hay a su vez un bug en el servidor de código del lado del que la hizo lucir como caché). En un completamente en blanco de la aplicación web, a la respuesta anterior, funciona.
    • muchas gracias por la información de la respuesta. De hecho, me comprobado todo , despejó el firefox historia, comprobar la respuesta de los encabezados de las herramientas del desarrollador y los encabezados de respuesta contiene la caché encabezados : Cache-Control must-revalidate,no-cache,no-store,max-age=0 Pragma no-cache Caduca Thu, 01 Jan 1970 00:00:00 GMT por favor Puede sugerir algo que podría causar el problema ?
    • He publicado mi pregunta aquí también en el caso de que quiera echar un vistazo . stackoverflow.com/questions/47204246/…

  2. 9

    También encontré otra buena solución.

    En faces-config.xml agregar

    <lifecycle>
        <phase-listener id="nocache">client.security.CacheControlPhaseListener</phase-listener>
    </lifecycle>

    Y aplicar la siguiente clase:

    package client.security;
    
    import javax.faces.context.FacesContext;
    import javax.faces.event.PhaseEvent;
    import javax.faces.event.PhaseId;
    import javax.faces.event.PhaseListener;
    import javax.servlet.http.HttpServletResponse;
    
    @SuppressWarnings("serial")
    public class CacheControlPhaseListener implements PhaseListener
    {
        public PhaseId getPhaseId()
        {
            return PhaseId.RENDER_RESPONSE;
        }
    
        public void afterPhase(PhaseEvent event)        
        {
        }
    
        public void beforePhase(PhaseEvent event)
        {
           FacesContext facesContext = event.getFacesContext();
           HttpServletResponse response = (HttpServletResponse) facesContext
                    .getExternalContext().getResponse();
           response.addHeader("Pragma", "no-cache");
           response.addHeader("Cache-Control", "no-cache");
           //Stronger according to blog comment below that references HTTP spec
           response.addHeader("Cache-Control", "no-store");
           response.addHeader("Cache-Control", "must-revalidate");
           //some date in the past
           response.addHeader("Expires", "Mon, 8 Aug 2006 10:00:00 GMT");
        }
    } 
    • Mientras que puede trabajar, utilizando un JSF fase de escucha, mientras que la misma funcionalidad también es posible con un filtro de servlets es como usar un martillo en lugar de un destornillador para conseguir un tornillo de abajo.
    • ¿a qué te refieres? «Mientras que puede trabajar, utilizando un JSF fase de escucha, mientras que la misma funcionalidad también es posible con un filtro de servlets es como usar un martillo en lugar de un destornillador para conseguir un tornillo de abajo.»

Dejar respuesta

Please enter your comment!
Please enter your name here