1

I have in my application polling HTTP requests that executed each 5 minutes.

I want to configure those URLs not to change the session expiration. Otherwise my session will never expired (and I do not want it). Was not able to find it in the web.xml and HttpSession documentation.

How is possible to do it?

Added

Very important clarification: the request should be authenticated. It means that the request should be attached to JsessionID that is already authenticated.

Clarification (Added 2)

I do not want the session will expire regardless of whether the user stays active or not. I want the session will expire on the user inactivity and will not be expire if user working on UI. I want the session will expire on the user inactivity in spite of polling requests that come each 5 minutes

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Michael
  • 10,063
  • 18
  • 65
  • 104
  • Don't attach jsessionId (remove it or set it to something else) to this request, so that server thinks that its a new request. – RP- Sep 19 '16 at 03:41
  • The request should be authenticated – Michael Sep 19 '16 at 14:44
  • jsessionid is the thing that the server depends on to identify the session. Can you get the user info using some other identifier like a different cookie and remove jsessionid from those requests? – RP- Sep 19 '16 at 18:49
  • If a request will use a different cookie it means additional authentication that not possible in my case. – Michael Sep 21 '16 at 06:33

4 Answers4

3

This is not supported by standard Servlet API.

Your best bet is to create a global servlet filter (with @WebFilter("/*")) which decreases the HttpSession#setMaxInactiveInterval() every time when the particular URL hits the server, and puts it back to the default value for other URLs. It only requires a bit of basic math.

The relevant bits of the implementation can look like this:

private static final int DEFAULT_EXPIRE_TIME_IN_SECONDS = 1800;
private static final String SKIP_EXPIRE_TIME_ON_URI = "/somePollServlet";

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpSession session = request.getSession();

    if (request.getRequestURI().equals(request.getContextPath() + SKIP_EXPIRE_TIME_ON_URI)) {
        long lastAccessedTime = session.getLastAccessedTime();
        long currentTime = System.currentTimeMillis();
        int newExpireTime = DEFAULT_EXPIRE_TIME_IN_SECONDS - (int) ((currentTime - lastAccessedTime) / 1000);
        session.setMaxInactiveInterval(newExpireTime);
    }
    else {
        session.setMaxInactiveInterval(DEFAULT_EXPIRE_TIME);
    }

    chain.doFilter(req, res);
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Can the filter read the session-timeout value from web.xml? ` 5 ` – Michael Sep 25 '16 at 11:47
  • 1
    @Michael: Also not by standard API: http://stackoverflow.com/q/17528373 Alternative is to remember first call on `getMaxInactiveInterval()` in session. – BalusC Sep 25 '16 at 12:14
1

This is the updated answer @BalusC. His solution is not fully work for me. Try this solution.

@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        int expireTimeInSeconds = 60;

        String skippableUrl = "/url";

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpSession session = request.getSession();

        int maxInactiveInterval = session.getMaxInactiveInterval();

        if (request.getRequestURI().equals(request.getContextPath() + skippableUrl )) {

            long lastAccessedTime = session.getLastAccessedTime();
            long currentTime = System.currentTimeMillis();
            int newMaxInactiveInterval = maxInactiveInterval - (int) ((currentTime - lastAccessedTime) / 1000);

            if (newMaxInactiveInterval <= 0 || maxInactiveInterval > expireTimeInSeconds) {
                session.invalidate();
            } else {
                session.setMaxInactiveInterval(newMaxInactiveInterval);
            }

        } else {
            session.setMaxInactiveInterval(expireTimeInSeconds);
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }
Udeesha Induwara
  • 605
  • 1
  • 10
  • 20
0

There are many approaches to doing this. One of them is to use a javascript for example JQuery . The main idea is regardless of whether a script is polling the server, if there is no activity on the application by the user for example key press, mouse movement etc for a reasonable duration, it needs to be considered that the user is not present and the javascript needs to call the logout url for your applications. Please refer to the provided URL that actually explains the concept very well.

Ironluca
  • 3,402
  • 4
  • 25
  • 32
  • How the plugin can distinguish between a request caused by a user activity (or example key press, mouse movement etc) and the pooling request? – Michael Sep 22 '16 at 05:26
  • User activities are generally modeled as events to the JS engine that can be handled, polling on the otherhand is an activity performed from within the engine e.g. $http calls in Angular etc. the events can be tracked by the framework and absence of any event for a specified period of time can be interpreted as no user activity – Ironluca Sep 22 '16 at 05:44
  • I can not change the existing UI due to one polling request. As I say in the question I need to configure the pooling URL – Michael Sep 22 '16 at 06:06
  • You may not need to change the polling behaviour of the UI, that may remain, what you need to do is to introduce some mechanism (adding new code or using a plugin) that can detect user inactivity and then may be intricude a parameter in the URL, based on which the server can invalidate the session. On the otherhand if you can integrate some plugin in your existing UI that can provide features similar to JQuery mentioned above, that will reduce your development efforts – Ironluca Sep 22 '16 at 07:02
  • I need to change the suggested plugin: it should ignore the pooling requests. – Michael Sep 22 '16 at 08:44
  • Yes, for example JQuery plugin will ignore any automated polling and will only track user activity – Ironluca Sep 22 '16 at 10:47
-1

In your case you need a Session management scheme that will expire in N minutes time regardless of whether the user stays active or not. That way you don't need to by pass any authentication or default cookies.

You can achieve it by using two methods proposed here.

  1. A Scheduled Job which invalidates the session after N minutes from login
  2. An Header and Filter based approach to decide the session expiration dynamically.
Community
  • 1
  • 1
shazin
  • 21,379
  • 3
  • 54
  • 71
  • it is not what I need. I do not want the session will expire regardless of whether the user stays active or not. I want the session will expire on the user inactivity and will not be expire if user working on UI. I want the session will expire on the user inactivity in spite of polling requests that come each 5 minutes – Michael Sep 21 '16 at 07:17