How do I execute an authenticated AJAX request without resetting the tomcat's session timeout?

前端 未结 2 1637
隐瞒了意图╮
隐瞒了意图╮ 2020-12-17 22:08

I\'ve got an existing Grails Web application that is in production and has a 30 minute session timeout. We are running Tomcat (tcServer).

When a user is authentic

2条回答
  •  感动是毒
    2020-12-17 22:52

    Nope not possible...

    One option is the following:

    1) create a javax.servlet.Filter and store the timestamp of the last (non-ajax) pageview on the session.

    2) create a javax.servlet.http.HttpSessionListener to store all the active sessions.

    3) use a background thread to invalidate all expired sessions.


    Sample Code:

    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class LastAccessFilter implements Filter, HttpSessionListener {
        private static final Object SYNC_OBJECT = new Object();
        private static final String LAST_ACCESSED = "lastAccessed";
        private boolean backgroundThreadEnabled;
    
        public void destroy() {
            synchronized (SYNC_OBJECT){
                backgroundThreadEnabled = false;
                SYNC_OBJECT.notifyAll();
            }
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            if (req instanceof HttpServletRequest) {
                HttpServletRequest httpServletRequest = (HttpServletRequest) req;
                if(!isAjax(httpServletRequest)){
                    httpServletRequest.getSession().setAttribute(LAST_ACCESSED, System.currentTimeMillis());
                }
            }
            chain.doFilter(req, resp);
        }
        public static boolean isAjax(request) {
           return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
        }   
        public void init(FilterConfig config) throws ServletException {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (LastAccessFilter.this.backgroundThreadEnabled) {
                        synchronized (SYNC_OBJECT) {
                            try {
                                SYNC_OBJECT.wait(3000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
    
                            if (LastAccessFilter.this.backgroundThreadEnabled) {
                                HttpSession[] sessions;
                                synchronized (activeSessions){
                                    sessions = activeSessions.toArray(new HttpSession[activeSessions.size()]);
                                }
                                cleanupInactiveSessions(sessions);
                            }
                        }
                    }
                }
    
                private void cleanupInactiveSessions(HttpSession[] sessions) {
                    for (HttpSession session : sessions) {
                        Object lastAccessedObject = session.getAttribute(LAST_ACCESSED);
                        if(lastAccessedObject == null) continue;
                        long lastAccessed = (Long)lastAccessedObject;
                        if(System.currentTimeMillis() > (lastAccessed + 1800000)){//30 Minutes
                            session.invalidate();
                        }
                    }
                }
            });
    
            t.setDaemon(true);
            this.backgroundThreadEnabled = true;
            t.start();
        }
    
        private final List activeSessions = new ArrayList();
    
        @Override
        public void sessionCreated(HttpSessionEvent httpSessionEvent) {
            synchronized (activeSessions) {
                this.activeSessions.add(httpSessionEvent.getSession());
            }
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
            synchronized (activeSessions) {
                this.activeSessions.remove(httpSessionEvent.getSession());
            }
        }
    }
    

提交回复
热议问题