【问题标题】:How to configure a maximum duration of an application session in Tomcat?如何在 Tomcat 中配置应用程序会话的最大持续时间?
【发布时间】:2019-06-05 02:08:20
【问题描述】:

我需要将 Tomcat 中应用程序会话的最长持续时间配置为 24 小时。

我无法在文档中找到合适的配置:

https://tomcat.apache.org/tomcat-8.5-doc/config/http.html

SSLHostConfigsessionTimeout,但我需要Connector配置;我们在Tomcat之前终止WebServer中的SSL连接,但由Tomcat处理会话管理。)

已添加

我们已经处理了会话过期超时 (Tomcat Session Timeout web.xml)。

最大持续时间超时意味着即使用户在所有时间内都处于活动状态,其应用程序会话也会在最大持续时间超时后失效。

【问题讨论】:

标签: tomcat session-management tomcat8.5


【解决方案1】:

HttpSessionListener 只会通知会话的创建和销毁,但不会在每个页面请求上调用。

我会实施一个过滤器来检查会话创建时间并使会话无效以及设置标题或重定向。

在 web.xml 中添加:

<filter>
    <filter-name>Max Session Duration</filter-name>
    <filter-class>com.your.package.MaxSessionDurationFilter</filter-class>
    <init-param>
        <!-- Maximum session duration in hours -->
        <param-name>maxduration</param-name>
        <param-value>24</param-value>
    </init-param>
</filter>

和类似的映射

<filter-mapping>
  <filter-name>Max Session Duration</filter-name>
  <url-pattern>*.jsp</url-pattern>
</filter-mapping>

那么过滤器的实现是这样的:

package com.your.package;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MaxSessionDurationFilter implements Filter {

    private final long oneHourMillis = 1000*60*60;

    private long maxDuration;

    private FilterConfig filterConfig;

    @Override
    public void init(FilterConfig fc) throws ServletException {
        filterConfig = fc;
        maxDuration = Long.parseLong(filterConfig.getInitParameter("maxduration"));
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
        throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) req;
        HttpServletResponse httpResp = (HttpServletResponse) resp;
        final long creationTime = httpReq.getSession().getCreationTime();
        final long currentTime = System.currentTimeMillis();
        if (currentTime-creationTime > maxDuration*oneHourMillis) {
            httpReq.getSession().invalidate();
            // Could also set headers to 403 forbidden
            // httpResp.setStatus(HttpServletResponse.SC_FORBIDDEN);
            httpResp.sendRedirect("expiredsession.jsp");
        } else {
            chain.doFilter(req, resp);
        }
    }

    @Override
    public void destroy() { }

}

【讨论】:

    【解决方案2】:

    可以实现HttpSessionListener 并在 24 小时后销毁会话:

    https://tomcat.apache.org/tomcat-8.5-doc/servletapi/javax/servlet/http/HttpSessionListener.html

    问题是否存在更好的方法。

    【讨论】:

      【解决方案3】:

      您可以使用setMaxInactiveInterval 配置会话的最长持续时间

      指定 servlet 容器使该会话无效之前客户端请求之间的时间(以秒为单位)。

      创建会话时更新,使用 HttpSessionListener 覆盖 sessionCreated 方法:

      public class MyHttpSessionListener implements HttpSessionListener{
        public void sessionCreated(HttpSessionEvent event){
          event.getSession().setMaxInactiveInterval(24*60*60); //24 Hours
        }
      

      使用 HttpSessionListener。在 sessionCreated() 方法中,您可以通过编程方式设置会话超时。

      【讨论】:

      • 不幸的是,我没有询问会话到期超时。我们已经通过web.xml&lt;session-config&gt; &lt;session-timeout&gt;配置了会话过期超时,即使我们一直有请求,我们也需要使会话无效。
      • @Michael 你可以添加 WebFilter 并设置 setMaxInactiveInterval stackoverflow.com/questions/39564955/…
      • 谢谢,但 setMaxInactiveInterval 不是我需要的。我确实知道使用 WebFilter 和 HttpSessionListener 的解决方案。询问您是否知道其他解决方案
      • @Michael 如果你保存了数据库登录时间,你可以有一个计划任务来发现一天内登录的用户并使他们的会话无效
      • 谢谢!这正是我的回答中描述的方法
      猜你喜欢
      • 2022-01-17
      • 2019-01-09
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 2018-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多