【问题标题】:How to disable JSESSIONID cookie-based (and any else) session-tracking features in jetty 9?如何在 jetty 9 中禁用基于 JSESSIONID cookie(以及任何其他)的会话跟踪功能?
【发布时间】:2013-06-20 03:49:50
【问题描述】:

我希望为我的无状态或手动维护状态 Spring MVC 应用程序禁用 Jetty 9 中的各种会话跟踪功能,但我找不到任何工作示例来说明如何做到这一点。

我尝试了以下/WEB-INF/spring-config.xml标签:

...
<security:http use-expressions="true"
               disable-url-rewriting="true"
               create-session="stateless">
...

在战争中与以下/WEB-INF/jetty-web.xml 描述符一起:

<?xml version="1.0"  encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <Get name="sessionHandler">
        <Get name="sessionManager">
            <Set name="usingCookies" type="boolean">false</Set>
        </Get>
    </Get>
</Configure>

但每当我试图打开我的应用程序的任何页面时,我仍然会收到 JSESSIONID cookie。任何提示为什么以及如何解决它?

【问题讨论】:

    标签: spring spring-mvc spring-security jetty


    【解决方案1】:

    使用 Spring Boot 实现 Pavel Horal suggested in his answer 的过程很简单:

    import org.springframework.boot.web.servlet.ServletContextInitializer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.Collections;
    
    @Configuration
    public class WebContainerConfiguration {
      @Bean
      public ServletContextInitializer servletContextInitializer() {
        return servletContext -> servletContext.setSessionTrackingModes(Collections.emptySet());
      }
    }
    

    为我工作得很好。谢谢!

    【讨论】:

      【解决方案2】:

      作为 user100464 建议的使创建的会话无效的替代方法,我使用了 HttpSessionListener,每当有人尝试打开会话时抛出异常,例如通过调用request.getSession(),并删除出现。

      public class PreventSessions implements HttpSessionListener {
      
          @Override
          public void sessionCreated(HttpSessionEvent se) {
              throw new UnsupportedOperationException("sessions are not allowed");
          }
      
          @Override
          public void sessionDestroyed(HttpSessionEvent se) {
              throw new UnsupportedOperationException("sessions are not allowed");
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以通过在请求完成后立即使会话无效来实现相同的目标。您可以使用 ServletRequestListener 来做到这一点,如下所示:

        public class SessionKiller implements ServletRequestListener {
        
            public void requestInitialized(ServletRequestEvent sre) {
                // no-op
            }
        
            public void requestDestroyed(ServletRequestEvent sre) {
                final HttpServletRequest servletRequest = (HttpServletRequest)sre.getServletRequest();
                final HttpSession session = servletRequest.getSession(false);
                if (session != null) {
                    session.invalidate();
                }
            }
        }
        

        要使用ServletRequestListener,请将以下内容添加到 webapp 的web.xml 中的web-app 元素:

        <listener>
          <listener-class>YOUR-PACKAGE-NAME.SessionKiller</listener-class>
        </listener>
        

        【讨论】:

          【解决方案4】:

          使用 servlet 3,可以将会话跟踪模式设置为 servlet 注册的一部分 - ServletContext#setSessionTrackingModes... 你可以试试。

          但是在你的情况下,我会调查谁在打电话给HttpServletRequest#getSession(...)。在这个方法中设置断点,看看是谁在调用它。您的应用程序中的某些代码正在初始化会话。

          【讨论】:

          • SessionTrackingModes 只允许您选择 URL、SSL 和 COOKIE 版本的跟踪,通过这种方式完全禁用它们是不可能的。在 Jetty 9 中,不是类似于 Tomcat 7 的 /META-INF/context.xml 文件,其内容为 &lt;Context disableURLRewriting="true" cookies="false" /&gt;,有效地禁用了会话的 URL 和 COOKIE 跟踪器,而不管是否调用了 getSession()?
          • 这意味着所有对getSession() 的调用都应该以错误告终。这不在 Servlet API 中,而且我不知道 Tomcat 中的这种配置(对 Jetty 不太熟悉)。但是,您可以实现自己的 servlet 过滤器并使用 HttpServletRequestWrapper 包装传入请求并自己执行此操作。但最终你将需要面对调用getSession() 的地方并摆脱它们。
          猜你喜欢
          • 1970-01-01
          • 2012-01-05
          • 2015-04-01
          • 2012-01-05
          • 2015-12-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多