2013-10-04 5 views
3

В моем приложении, которое работает с Spring Web MVC на Tomcat 7.0, у меня есть определенные контроллеры, где, хотя запросы на них потребуют проверки подлинности и действительного сеанса, я не хочу, чтобы временная метка истечения сеанса быть обновленным. Другими словами, я хочу, чтобы сессия заканчивалась именно тогда, когда бы не было этого конкретного HTTP-запроса.Контролировать, обновляется ли временная метка сеанса

Это методы AJAX, если это имеет значение, хотя я не знаю, если это так.

Можно ли это сделать либо с помощью общей Java EE, либо с помощью некоторых специальных крючков Tomcat? Есть ли другой способ достичь этого? Я знаю о http://download.oracle.com/javaee/6/api/javax/servlet/http/HttpSession.html#setMaxInactiveInterval%28int%29, но это кажется почти противоположным тому, что я хочу.

ответ

2

Доступ время обновляется только когда сессия being accessed byHttpServletRequest#getSession. Поэтому, если вы убедитесь, что вы не подделываете сеанс, вы должны быть в порядке.ОБНОВЛЕНИЕ: на основе the JavaDoc вышеизложенное не соответствует действительности (даже я тщательно искал исходный код и не нашел какой-либо части кода, ответственного за такое поведение).

С другой стороны, если вам нужно получить доступ к сеансу в своем запросе AJAX, вы в значительной степени ввернуты. Единственное решение, о котором я могу думать, - это сохранить lastAccessTime вручную (например, в сервлет-фильтре), а затем проверить тайм-аут сеанса и invalidate the session manually (например, в том же фильтре). Это должно быть довольно просто и легко реализовать.


UPDATE: Просто для удовольствия я реализовал фильтр (не проверено):

public class SessionInvalidationFilter implements Filter { 

    private static final String LAST_ACCESS_SESSION_ATTR = "lastAccessTime"; 

    private static final long SESSION_TIMEOUT = 1000 * 60 * 20; // 20 minutes 

    private static final String IGNORE_ACCESS_URI = "/this/will-not/update/access-time"; 

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

    @Override 
    public void destroy() { 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 
     // Cast to HTTP request and response 
     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     HttpServletResponse httpResponse = (HttpServletResponse) response; 
     // Check if we are handling standard request 
     if (!IGNORE_ACCESS_URI.equals(httpRequest.getRequestURI())) { 
      chain.doFilter(new SessionAccessAwareRequest(httpRequest), response); 
      return; 
     } 
     // Now we can handle the special case of non-tracked request 
     boolean expired = false; 
     HttpSession session = httpRequest.getSession(false); 
     if (session == null) { 
      // No session means the AJAX contained no or incorrect JSESSIONID 
      expired = true; 
     } else { 
      Long lastAccessTime = (Long) session.getAttribute(LAST_ACCESS_SESSION_ATTR); 
      if (lastAccessTime == null || lastAccessTime + SESSION_TIMEOUT < System.currentTimeMillis()) { 
       session.invalidate(); // Invalidate manually 
       expired = true; 
      } 
     } 
     // Handle error or process normally 
     if (expired) { 
      httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST); 
     } else { 
      chain.doFilter(request, response); 
     } 
    } 

    private static class SessionAccessAwareRequest extends HttpServletRequestWrapper { 

     public SessionAccessAwareRequest(HttpServletRequest request) { 
      super(request); 
     } 

     @Override 
     public HttpSession getSession() { 
      return getSession(true); 
     } 

     @Override 
     public HttpSession getSession(boolean create) { 
      HttpSession session = super.getSession(create); 
      if (session != null) { 
       session.setAttribute(LAST_ACCESS_SESSION_ATTR, System.currentTimeMillis()); 
      } 
      return session; 
     } 

    } 

} 
+0

Я не могу найти какой-либо 'access' метод в [' HttpSession'] (HTTP : //docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSession.html#method_summary). –

+1

Кстати, каждый раз, когда вы отправляете запрос на сервер, оставшееся время истечения сеанса * сбрасывается * (даже при использовании вызовов ajax). –

+0

'access' - это метод внутренней каталинии, который не относится к спецификации сервлетов (проверьте ссылку GitHub в моем ответе). Последнее * время доступа * обновляется, вероятно, потому, что ваше приложение получает доступ к сеансу без вашего ведома (например, весенняя безопасность или какой-либо другой компонент). –

Смежные вопросы