java 我可以关闭web.xml中的HttpSession吗?

8iwquhpp  于 2022-11-20  发布在  Java
关注(0)|答案(9)|浏览(159)

我想完全消除HttpSession-我可以在web.xml中做到这一点吗?我确信有特定于容器的方法可以做到这一点(这就是我在Google搜索时拥挤搜索结果的原因)。
这是个坏主意吗?我更喜欢完全禁用东西,直到我真正需要它们。

zour9fqk

zour9fqk1#

  • 我希望完全消除HttpSession *

您不能完全禁用它。您所需要做的只是而不是通过request.getSession()request.getSession(true)在Web应用程序代码中的任何位置获取它的句柄,并确保您的JSP不会通过设置<%@page session="false"%>隐式地这样做。
如果您主要关心的是禁用HttpSession后台使用的cookie,那么在Java EE 5 / Servlet 2.5中,您只能在特定于服务器的Web应用程序配置中这样做。例如,在Tomcat中,您可以在<Context>元素中将cookies属性设置为false

<Context cookies="false">

也可以参考Tomcat specific documentation。这样的话,会话就不会在后续的请求中被保留,因为这些请求没有被URL重写--只有当你出于某种原因从请求中获取它的时候。毕竟,如果你不需要它,不获取它,那么它就根本不会被创建/保留。
或者,如果您已经使用了Java EE 6 / Servlet 3.0或更高版本,并且确实希望通过web.xml执行此操作,则可以使用web.xml中的新<cookie-config>元素将最大年龄清零,如下所示:

<session-config>
    <session-timeout>1</session-timeout>
    <cookie-config>
        <max-age>0</max-age>
    </cookie-config>
</session-config>

如果要在Web应用程序中硬编码,以便getSession()永远不会返回HttpSession(或“空”HttpSession),则需要创建一个监听/*url-pattern的过滤器,该过滤器将HttpServletRequest替换为HttpServletRequestWrapper实现,该实现在所有getSession()方法上返回null,或者是一个不执行任何操作甚至抛出UnsupportedOperationException的伪定制HttpSession实现。

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request) {
        @Override
        public HttpSession getSession() {
            return null;
        }
        @Override
        public HttpSession getSession(boolean create) {
            return null;
        }
    }, response);
}
  • 附言:这是个坏主意吗?我更喜欢完全禁用东西,直到我真正需要它们。*

如果你不需要它们,就不要用它们。仅此而已。真的:)

9vw9lbht

9vw9lbht2#

如果您正在构建一个无状态的高负载应用程序,您可以禁止使用cookie进行会话跟踪,如下所示(非侵入式,可能与容器无关):

<session-config>
    <tracking-mode>URL</tracking-mode>
</session-config>

要强制执行此架构决策,请编写如下代码:

public class PreventSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
    throw new IllegalStateException("Session use is forbidden");
}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
    throw new IllegalStateException("Session use is forbidden");
}
}

并将其添加到web.xml中,修复出现异常的地方:

<listener>
    <listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class>
</listener>
sf6xfgos

sf6xfgos3#

在带有Java Config的Spring Security 3中,您可以使用HttpSecurity.sessionManagement():

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

Xml看起来像这样;

<http create-session="stateless">
  <!-- config -->
</http>

顺便说一下,NEVER和STATELESS之间的区别
NEVER:Spring Security永远不会创建HttpSession,但如果HttpSession已经存在,则会使用它
STATELESS:Spring Security永远不会创建HttpSession,也永远不会使用它来获取SecurityContext

lsmepo6l

lsmepo6l4#

我使用下面的方法为我的RESTful应用程序删除任何无意中创建 * 和 * 使用的会话cookie。

<session-config>
    <session-timeout>1</session-timeout>
    <cookie-config>
        <max-age>0</max-age>
    </cookie-config>
</session-config>

然而,这并不能完全关闭HttpSessions。应用程序仍可能无意中创建会话,即使它在一分钟内消失,并且恶意客户端也可能忽略cookie的最大年龄请求。
这种方法的优点是您不需要更改应用程序,只需更改web.xml即可。我建议您创建一个HttpSessionListener,它将记录会话的创建或销毁时间,以便您可以跟踪会话的发生时间。

4nkexdtk

4nkexdtk5#

我想完全消除HttpSession-我可以在web.xml中做到吗?我确信有特定于容器的方法可以做到这一点
我不这么认为。禁用HttpSession将违反Servlet规范,该规范规定HttpServletRequest#getSession应返回一个会话或创建一个会话。因此,我不希望Java EE容器提供这样的配置选项(这将使其不兼容)。
这是个坏主意吗?我更喜欢完全禁用东西,直到我真正需要它们。
好吧,我不太明白这一点,只是如果你不想使用它,就不要在会话中放置任何东西。现在,如果你真的想阻止会话的使用,你可以使用Filter来替换请求,用HttpServletRequestWrapper的实现来覆盖getSession()。但是我不会浪费时间实现这个:)

**更新:*我最初的建议不是最佳的,“正确”( 咳嗽 *)的方法是替换请求。

zpqajqem

zpqajqem6#

从Servlet 3.0开始,您可以通过向ServletContextListenercontextInitialized方法添加如下代码,使servlet容器不以任何方式跟踪会话:

servletContext.setSessionTrackingModes(Collections.emptySet());

Javadoc的名称。

ogsagwnx

ogsagwnx7#

您可以使用URL重写过滤器(如tuckey rewrite filter)重写URL,而不是禁用。这将给予Google友好的结果,但仍允许基于cookie的会话处理。
然而,你可能应该对所有的响应禁用它,因为它比搜索引擎不友好更糟糕。它暴露了可以用于certain security exploits的会话ID。
Tuckey筛选器的Example config

<outbound-rule encodefirst="true">
  <name>Strip URL Session ID's</name>
  <from>^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$</from>
  <to>$1$2$3</to>
</outbound-rule>
7dl7o3gd

7dl7o3gd8#

会话的创建是不可避免的,但是您可以在请求周期结束时检查是否违反了您自己的要求。因此,创建一个简单的servlet过滤器,将其放在chain的第一个和第二个位置。如果创建了会话,doFilter会抛出异常:

chain.doFilter(request, response);
if(request.getSession(false) != null)
    throw new RuntimeException("Somewhere request.getSession() was called");
yqlxgs2m

yqlxgs2m9#

对于RESTful应用程序,我只是在每次请求的生命周期结束时使其无效。可能有一些Web服务器在新客户端访问时总是创建新的会话,无论您是否调用request.getSession()

相关问题