2012-07-05 33 views
14

Bueno, yo he terminado con esto ...JsessionId - cómo evitar; jsessionid = XXX en la primera llamada a una página? funciona si la primera página JSP es

que tiene una aplicación que utiliza el index.jsp bienvenida páginas con un <iframe></iframe> el contenido del iframe es una página JSF. Si accedo index.jsp Veo una cookie que ya están en la primera ponerse en Firebug:

Set-Cookie JSESSIONID=C615DA89B6EF73F801973EA3DCD3B226; Path=/ 

La página de los hereda esta JSESSIONID. PERO: cuando accedo directamente a la página del <iframe/>, obtengo el jsessionId reescrito en todas las URL sin una cookie, en la primera solicitud. Luego se usa la cookie. Todo está bien, si: El sistema de seguridad me permitiría realizar reescrituras de URL.

corro JBoss 4.2.2

que quiero lograr el mismo comportamiento que tengo con el index.jsp - por ejemplo, siempre use cookies y siempre evite reescribir http.

[EDIT] gracias a la respuesta de balusc escribí esto:

public class JsessionIdAvoiderFilter implements Filter { 

      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, 
        ServletException { 
       boolean allowFilterChain = redirectToAvoidJsessionId((HttpServletRequest) req, (HttpServletResponse)res); 

         //I'm doing this because if I execute the request completely, it will perform a pretty heavy lookup operation. No need to do it twice. 
       if(allowFilterChain) 
        chain.doFilter(req, res); 
      } 


      public static boolean redirectToAvoidJsessionId(HttpServletRequest req, HttpServletResponse res) { 
       HttpSession s = req.getSession(); 
       if(s.isNew()) { 

//after the redirect we don't want to redirect again. 
if(!(req.isRequestedSessionIdFromCookie()&&req.isRequestedSessionIdFromURL())) 
        { 
           //yeah we have request parameters actually on that request.   
         String qs = req.getQueryString(); 

         String requestURI = req.getRequestURI(); 
         try { 
          res.sendRedirect(requestURI+"?"+qs); 
          return false; 
         } catch (IOException e) { 
          logger.error("Error sending redirect. " + e.getMessage()); 
         } 
        } 
       } 
       return true; 
      } 
} 

No olvide añadirlo a su web.xml

<filter> 
    <display-name>JsessionId Filter</display-name> 
    <filter-name>jsessionIdAvoiderFilter</filter-name> 
    <filter-class>my.namespace.JsessionIdAvoiderFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>jsessionIdAvoiderFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<filter> 

Respuesta

12

Desde Servlet 3.0 se puede utilizar <tracking-mode>COOKIE</tracking-mode> para esta. Pero como JBoss 4.2.2 no es un compilador de Servlet 3.0, esta no es una opción.

Lo más fácil sería crear un filtro de servlet que envíe una redirección a HttpServletRequest#getRequestURI() cuando HttpSession#isNew() devuelve true. No olvide verificar el HttpServletRequest#isRequestedSessionIdFromCookie() para evitar un bucle de redirección infinito cuando el cliente no admite cookies en absoluto.

+1

gracias. ¿Hay una 'donación para la bondad del cerdo afortunado' en su sitio web? ¿Puedo pedirle una pizza? – Toskan

+0

De nada. En la columna de la derecha de mi sitio web/blog, puede encontrar un botón de donación de PayPal. Esa es la única forma hasta ahora. – BalusC

+0

parece que no puedo enviarle un mensaje personal. Debes averiguar cómo forzar que PayPal sea inglés. Ese holandés es un poco confuso :-) "Snel doneren" :-D – Toskan

2

Esto se puede hacer con un filtro simple que envuelve la solicitud con un HttpServletRequest que anula HttpServletRequest.encodeURL y HttpServletRequest.encodeRedirectURL. Simplemente devuelva el argumento String que se le haya pasado e inhabilitará la reescritura de URL. Tenga en cuenta que esto solo funcionará para una sola aplicación web a menos que desee configurarla en conf/web.xml (no recomendado) o configurarla en todas sus aplicaciones web diferentes.

Esta técnica es superior a la que se publicó más adelante en su pregunta porque no requiere redirección, lo que puede ralentizar sus solicitudes. OMI, también es más limpio.

+0

lo echaré un vistazo lo antes posible. ¿A qué te refieres con la aplicación web "única"? No estoy muy seguro de lo que quiere decir – Toskan

+0

Los filtros están configurados en 'WEB-INF/web.xml' que solo protegerá una aplicación web como se describe. –

+0

La razón por la que acepto la respuesta de balusc es porque eso es lo que implementé y se adapta bien al problema descrito. No tengo tiempo para probar su solución, pero suena bien. – Toskan

3

Según la recomendación de Christopher Schultz, probé esto y funciona.

package com.rama.test.jsessionfilter 

    public class JsessionIdAvoiderFilter implements Filter { 

     protected static final Logger LOGGER = LogManager.getLogger(JsessionIdAvoiderFilter.class); 

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

      if (!(req instanceof HttpServletRequest)) { 
       chain.doFilter(req, res); 
       return; 
      } 

      HttpServletRequest request = (HttpServletRequest) req; 
      HttpServletResponse response = (HttpServletResponse) res; 

     // Redirect requests with JSESSIONID in URL to clean old links 
     /* If you really want clean up some old links which have Jsession id bookmarked clean it. If its new app 
      this below check is not required. */ 
      if (request.isRequestedSessionIdFromURL()) { 
       String url = request.getRequestURL().append(request.getQueryString() != null ? "?" 
           + request.getQueryString() : "").toString(); 
       response.setHeader("Location", url); 
       response.sendError(HttpServletResponse.SC_MOVED_PERMANENTLY); 
       LOGGER.info(" Found url with jsession id in it:"+ request.getRequestURL() +": url="+url); 
       return; 
      } 

      // Prevent rendering of JSESSIONID in URLs for all outgoing links 
      HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(
        response) { 
       @Override 
       public String encodeRedirectUrl(String url) { 
        return url; 
       } 

       @Override 
       public String encodeRedirectURL(String url) { 
        return url; 
       } 

       @Override 
       public String encodeUrl(String url) { 
        return url; 
       } 

       @Override 
       public String encodeURL(String url) { 
        return url; 
       } 
      }; 
      chain.doFilter(req, wrappedResponse); 

     } 

     public void destroy() { 
     } 

     public void init(FilterConfig arg0) throws ServletException { 
     } 
    } 

y la siguiente entrada en web.xml

<filter> 
     <display-name>JsessionId Filter</display-name> 
     <filter-name>jsessionIdAvoiderFilter</filter-name> 
     <filter-class>com.rama.test.jsessionfilter.JsessionIdAvoiderFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>jsessionIdAvoiderFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
     <dispatcher>REQUEST</dispatcher> 
    </filter-mapping> 

Funciona muy bien !!!.

+0

Si las cookies están deshabilitadas, es mejor que revise su código y proporcione un advertencia. La suposición es que la cookie está habilitada en el lado del cliente. – Reddymails

Cuestiones relacionadas