2012-07-05 35 views
14

i Vâng đang thực hiện với điều này ...JsessionId - cách tránh, jsessionid = XXX trong lần gọi đầu tiên tới trang? nó hoạt động nếu trang đầu tiên là jsp

Tôi có một ứng dụng mà sử dụng các index.jsp chào đón trang với một <iframe></iframe> các nội dung của khung nội tuyến là một trang JSF. Nếu tôi truy cập vào index.jsp, tôi thấy cookie đã có trong lần truy cập đầu tiên trong firebug:

Set-Cookie JSESSIONID=C615DA89B6EF73F801973EA3DCD3B226; Path=/ 

Trang của kế thừa jsessionid này. NHƯNG: khi tôi truy cập trực tiếp vào trang của <iframe/> Tôi nhận được jsessionId được viết lại cho tất cả các URL không có cookie - theo yêu cầu đầu tiên. Sau đó, cookie được sử dụng. Điều này là tốt - nếu: Hệ thống bảo mật sẽ cho phép tôi thực hiện ghi đè url.

Tôi chạy jboss 4.2.2

Tôi muốn đạt được hành vi tương tự như tôi có với index.jsp - ví dụ: luôn sử dụng cookie và luôn tránh viết lại http.

[EDIT] nhờ câu trả lời balusc của tôi đã viết này:

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; 
      } 
} 

Đừng quên để thêm nó vào bạn 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> 

Trả lời

12

Kể từ Servlet 3.0 bạn có thể sử dụng <tracking-mode>COOKIE</tracking-mode> cho điều này. Nhưng như JBoss 4.2.2 không phải là trình biên dịch Servlet 3.0, đây không phải là một lựa chọn.

Dễ nhất là tạo bộ lọc servlet gửi chuyển hướng đến HttpServletRequest#getRequestURI() khi HttpSession#isNew() trả lại true. Đừng quên kiểm tra các HttpServletRequest#isRequestedSessionIdFromCookie() để ngăn chặn một vòng lặp chuyển hướng vô hạn khi khách hàng không hỗ trợ cookie cả.

+1

cảm ơn. Có một 'tặng cho lòng tốt lợn may mắn' trên trang web của bạn ở đâu đó? Tôi có thể gọi cho bạn pizza không? – Toskan

+0

Bạn được chào đón. Trên cột bên phải của trang web/blog của tôi, bạn có thể tìm thấy một nút đóng góp paypal. Đó là cách duy nhất cho đến nay. – BalusC

+0

có vẻ như tôi không thể gửi cho bạn một tin nhắn cá nhân. Bạn nên tìm ra cách để buộc paypal là tiếng anh. Tiếng Hà Lan đó hơi khó hiểu :-) "Snel doneren" :-D – Toskan

2

Điều này có thể được thực hiện với một Bộ lọc đơn giản kết thúc tốt đẹp yêu cầu với một HttpServletRequest ghi đè lên HttpServletRequest.encodeURL và HttpServletRequest.encodeRedirectURL. Chỉ cần trả về đối số String được truyền cho nó và bạn sẽ vô hiệu hóa việc viết lại URL. Lưu ý rằng điều này sẽ chỉ hoạt động cho một ứng dụng web duy nhất trừ khi bạn muốn định cấu hình nó trong conf/web.xml (không được khuyến nghị) hoặc định cấu hình nó trong tất cả các ứng dụng web riêng biệt của bạn.

Kỹ thuật này cao hơn kỹ thuật được đăng sau này trong câu hỏi của bạn bởi vì nó không yêu cầu chuyển hướng có thể làm chậm yêu cầu của bạn. IMO, nó cũng sạch hơn.

+0

tôi sẽ xem xét nó càng sớm càng tốt. Ý của bạn là gì với webapp "đơn"? Tôi không hoàn toàn chắc chắn ý bạn là gì – Toskan

+0

Các bộ lọc được cấu hình trong 'WEB-INF/web.xml' sẽ chỉ bảo vệ một webapp như được mô tả. –

+0

lý do tôi chấp nhận câu trả lời balusc là bởi vì đó là những gì tôi đã thực hiện và nó phù hợp với vấn đề được mô tả - Tôi không có thời gian thử giải pháp của bạn nhưng nó nghe có vẻ tốt – Toskan

3

Dựa trên đề xuất của Christopher Schultz, tôi đã thử cách này và nó hoạt động.

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 { 
     } 
    } 

và mục sau trong 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> 

Các công trình lớn !!!.

+0

Nếu cookie bị vô hiệu hóa, bạn nên kiểm tra mã của bạn và đưa ra cảnh báo. Giả định là cookie được bật ở phía máy khách. – Reddymails

Các vấn đề liên quan