0

I use Spring Session and I am having issues with session management especially dealing with session expiration.

The idea is to return a custom Http Header to the client e.g. X-Application-Session-Is-New if the session has expired.

Here is what I came up with:

public class SessionDestroyedFilter extends OncePerRequestFilter {

    //TODO: not always invoked!!
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (isAjaxRequest(request) && (isRequestedSessionInvalid(request) || isSessionNew(request))) {
            response.addHeader("X-Application-Session-Is-New", "true");
        }
        filterChain.doFilter(request, response);
    }

    private boolean isRequestedSessionInvalid(HttpServletRequest request) {
        return !request.isRequestedSessionIdValid();
    }

    private boolean isSessionNew(HttpServletRequest request) {
        return request.getSession(false).isNew();
    }

    private boolean isAjaxRequest(HttpServletRequest request) {
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }
}

The issue is that my filter does not seem to be always invoked upon session expiration perhaps because the request is not an ajax request and a new session ID is immediately created after that.

Can anyone please point me to an appropriate strategy to deal with session expiration on single page apps?

balteo
  • 23,602
  • 63
  • 219
  • 412

2 Answers2

1

EDIT Following is currently not possible (instead do decoration) Here are some related github issues (comment on them to fix them faster)

https://github.com/spring-projects/spring-session/issues/243

https://github.com/spring-projects/spring-session/issues/112

To accomplish this you have to use your own HttpSessionStrategy.

Here is an example if you are using CookieHttpSessionStrategy (the default one)

public class CustomHttpSessionStrategy extends CookieHttpSessionStrategy {
    @Override
    public void onInvalidateSession(HttpServletRequest request, HttpServletResponse response) {
        super.onInvalidateSession(request, response);
        response.addHeader("X-Application-Session-Is-New", "true");
    }
}

If you want to add your header on new sessions also consider overriding onNewSession(Session, HttpServletRequest, HttpServletResponse).

tsachev
  • 1,111
  • 10
  • 14
  • Hi tsachev. eh eh. CookieHttpSessionStrategy is final :-( – balteo Sep 20 '15 at 20:51
  • Then you need to decorate it I guess. and please vote for this issue https://github.com/spring-projects/spring-session/issues/243 so they fix it. – tsachev Sep 20 '15 at 21:00
  • Hi again Tsachev. Can you please explain how the HttpSessionStrategy is different to the Filter strategy? – balteo Sep 21 '15 at 10:32
  • Well in a filter the session might not yet be created, or the response may already be committed. Spring session repository filter creates a response wrapper and writes the cookie as late as possible, using http session strategy. – tsachev Sep 21 '15 at 13:52
0

This is Wrong

Please see my other answer

You should move your logic for adding X-Application-Session-Is-New after request is processed. Try something like

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    filterChain.doFilter(request, response);
    if (isAjaxRequest(request) && (isRequestedSessionInvalid(request) || isSessionNew(request))) {
        response.addHeader("X-Application-Session-Is-New", "true");
    }
}
tsachev
  • 1,111
  • 10
  • 14