2008-10-31 41 views
8

Estoy desarrollando una aplicación web java utilizando servlet, para evitar que el usuario presione el botón Atrás para ver información de usuarios anteriores, tengo el siguiente código:Cómo evitar que un usuario vea información de usuarios anteriores al presionar el botón "Atrás"

 protected void processRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException 
     {   
     HttpSession session=request.getSession(true); 

     response.setContentType("text/html"); 
     response.setHeader("Cache-Control","no-cache,no-store"); 
     response.setDateHeader("Expires",0); 
     response.setHeader("Pragma","no-cache"); 

     ...... 

     // if (!User_Logged_In) 
     session.invalidate(); 
     } 

además también tengo el siguiente código en el archivo: web/wEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
...... 
<filter> 
    <filter-name>ResponseHeaderFilter</filter-name> 
    <filter-class>ResponseHeaderFilter</filter-class> 
    <init-param> 
    <param-name>Cache-Control</param-name> 
    <param-value>private,no-cache,no-store</param-value> 
    </init-param> 
    <init-param> 
    <param-name>Pragma</param-name> 
    <param-value>no-cache</param-value> 
    </init-param> 
    <init-param> 
    <param-name>Expires</param-name> 
    <param-value>0</param-value> 
    </init-param> 
</filter> 

</web-app> 

Y el ResponseHeaderFilter.java se ve así:

import java.io.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 
import java.util.*; 

public class ResponseHeaderFilter implements Filter 
{ 
    FilterConfig fc; 

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

    for (Enumeration e=fc.getInitParameterNames();e.hasMoreElements();)  // Set the provided HTTP response parameters 
    { 
     String headerName=(String)e.nextElement(); 
     response.addHeader(headerName,fc.getInitParameter(headerName)); 
    } 
    chain.doFilter(req,response);            // Pass the request/response on 
    } 

    public void init(FilterConfig filterConfig) 
    { 
    this.fc=filterConfig; 
    } 

    public void destroy() 
    { 
    this.fc=null; 
    } 
} 

Hasta el momento todavía no está funcionando correctamente. El botón Atrás abrirá una ventana de advertencia que indica que los datos han expirado, pregunta si el usuario desea reenviarlo. Si elige sí, seguirá mostrando la información de las páginas anteriores. ¿Qué estoy haciendo mal? ¿Cuál es la solución?

Frank


Sí, estoy desarrollando una aplicación web de un PC en un lugar público, si el usuario B golpea el botón de retroceso que podría ver información privada del usuario A.

Estaba tratando de usar la identificación de sesión con servlet, pero ¿cómo hacerlo? ¿Algún código de muestra?

También probé el siguiente:

<Html> 
<Head>...</Head> 
<Body onLoad=document.execCommand("ClearAuthenticationCache","false")> 
...... 
<script type="text/javascript"> 
    // Clear current credentials : Requires IE6 SP1 or later 
    // document.execCommand("ClearAuthenticationCache"); 
    document.execCommand("ClearAuthenticationCache","false"); 
    </script> 
...... 
</Html> 

Funciona para IE pero pero Firefox.

Respuesta

3

Romper el botón Atrás es un pecado capital de desarrollo web.

pero podría intentar con un poco de script java en la actualización que actualizó los detalles de acuerdo con la sesión actualmente iniciada.

+1

Rompiendo el botón de retroceso sólo es relevante en una sola sesión. Por ejemplo, no puedo abrir una nueva ventana del navegador y presionar el botón "Atrás" para ir al último sitio web que visité. – sep332

1

No estoy seguro si entiendo su problema exactamente. ¿Le preocupa que la persona A cierre sesión, la persona B inicia sesión desde la misma PC y la misma instancia del navegador, y luego quiere evitar que la persona B vea lo que A estaba viendo?

Si es así, debería ser suficiente para verificar las credenciales del usuario en cada carga de página. Verifique que el usuario actual esté autorizado para ver los datos solicitados.

12

¿Cómo presionará el botón Atrás hará que el usuario vea otro ¿Datos del usuario? ¿Cuál es tu caso de uso? ¿Está diseñado para una terminal pública, donde cada usuario envía datos y luego se va? En este caso, asocie cada entrada con una ID de sesión única. Mantenga un registro de las ID de sesión válidas en su servidor. Una vez que se envía la entrada, elimine esa identificación de sesión de los ID válidos. Si aparece nuevamente, entonces no muestre la información.

+0

Estoy de acuerdo, parece que intenta resolver un problema que no debería existir ... ¿ejecutar la sesión como singleton o algo así? – GalacticCowboy

10

Tu problema es que estás intentando evitar que el cliente vea lo que está en su computadora. No puede evitar que vean su caché de navegador. No puede impedir que desactive JavaScript (y, por lo tanto, su código de secuencia de comandos). No puede evitar que usen un navegador que no observe esa convención de "reenvío" que usted menciona.

Esto no es un problema que se pueda resolver con JavaScript o una solución del lado del servidor. Esa parte de por qué "romper el botón de atrás" está mal visto: en realidad no resuelve nada.

+0

En realidad, puede desactivar el almacenamiento en caché. La mayoría de los navegadores lo respetan, pero no está garantizado. – sep332

+0

Como mencioné en mi publicación aquí, puede desactivar el almacenamiento en caché, pero el historial puede ser tratado de manera diferente por diferentes agentes de usuario. La especificación HTTP hace una distinción entre los dos, pero realmente no define el concepto de historia y define el almacenamiento en caché. – laz

-1

Tuve un problema similar en.Red. Agregué el siguiente javascript a mi página de cierre de sesión:

document.execCommand ("ClearAuthenticationCache", "false");

ahora si presiona el botón Atrás necesita autenticarse de nuevo.

+4

¿Ha considerado que un usuario malintencionado simplemente podría desactivar Javascript? – Zarkonnen

2

Parece que su verdadero problema es que el re-post funciona. Eso probablemente se deba a que:

credenciales
  1. están confiando desde el navegador en lugar de la sesión actual, o
  2. no están comprobando que en la sesión actual se permite el acceso a los datos representados por un valor de clave/identificador enviado desde el navegador

Recomiendo que después de que un usuario haya iniciado sesión nunca confíe en un nombre de usuario enviado por el navegador. Lo ideal sería utilizar los servicios de seguridad de un marco como Spring Security, pero en su ausencia puede confiar en HttpServletRequest.getUserPrincipal().

Para asegurarse de que la sesión actual tenga acceso a los datos, puede usar un mecanismo de Lista de control de acceso proporcionado por un marco como Spring Security o incluir una cláusula WHERE OWNER=? en las consultas de su base de datos.

0

Si le preocupa que alguien vea lo que estaba en un formulario en una página anterior, podría usar un formulario oculto para la publicación "real" y usar uno que sea solo para mostrarlo al usuario. Cuando el usuario envía el formulario de visualización, copia todos los campos en el formulario oculto, borra el formulario de visualización y luego envía el oculto.

Estoy de acuerdo con todos los demás: juguetear con el botón Atrás esta es una mala forma de manejar la información de protección.

0

No estoy 100% seguro de que esto sea una solución a su problema, ya que no entiendo completamente cómo podría recuperar el uso de los datos de otro usuario. Sin embargo, sé que para las aplicaciones web que desarrollo intento utilizar exclusivamente Redirect After Post para evitar el botón Atrás y actualizar los envíos de formularios duplicados.

0

Jeff Atwood describió una forma de evitar los ataques CSRF y XSRF here.

Puede utilizar esta técnica para resolver su problema "viendo lo que no deben ver".

1

No estoy seguro de entender su problema correctamente, pero parece que está permitiendo rePOSTs.

Un enfoque para evitar el reenvío es utilizar tokens. Coloque un token aleatorio en la forma y la sesión. En el registro, presentación que el testigo suministrado coincide con la señal en la sesión

  • si lo hace, cambiar el token en la sesión con una fresca y procesar la solicitud
  • de lo contrario dejar de procesar la solicitud).
1

Todos los navegadores tienen diferentes comportamientos y peculiaridades en lo que se refiere a la historia relacionada con la memoria caché y los diversos encabezados disponibles para controlarla. Firefox 3 funciona de forma diferente a Firefox 2, vuelve a mostrar datos potencialmente confidenciales cuando un usuario hace clic en el botón Atrás a pesar de utilizar directivas de caché para evitarlo.La mejor solución es utilizar una cookie de sesión que no se conserva e informar al usuario de la necesidad de cerrar la ventana del navegador después de cerrar la sesión. Especialmente si están en una terminal pública. Es doloroso, lo sé, pero las ofertas actuales de navegadores y la especificación HTTP no proporcionan ningún mecanismo para tratar el historial del navegador. El historial puede tratarse de manera diferente a la caché de un agente de usuario de acuerdo con la especificación HTTP. Consulte 13.13 History Lists como se define en RFC 2616 Protocolo de transferencia de hipertexto - HTTP/1.1 para el problema y la justificación.

0

Creo que esto es tanto un desafío de interfaz de usuario como un problema de codificación. Además de las técnicas contra caché que emplee, debe dejar en claro al usuario que debe presionar un botón grande y obvio de "Cerrar sesión" (o equivalente) cuando haya terminado.

0

si esto puede ayudar. Esto funciona para ASP, use una solución equivalente para otros idiomas.

Cuestiones relacionadas