Java 我可以在web.xml中关闭HttpSession吗?
我想完全消除HttpSession—我可以在web.xml中这样做吗?我确信有一些特定于容器的方法可以做到这一点(这就是我在谷歌搜索时会聚集搜索结果的原因) 这是个坏主意吗?在我真正需要它们之前,我宁愿完全禁用它们 我想完全消除HttpSession—我可以在web.xml中这样做吗?我相信有一些特定于容器的方法可以做到这一点 我不这么认为。禁用Java 我可以在web.xml中关闭HttpSession吗?,java,session,web-applications,web.xml,Java,Session,Web Applications,Web.xml,我想完全消除HttpSession—我可以在web.xml中这样做吗?我确信有一些特定于容器的方法可以做到这一点(这就是我在谷歌搜索时会聚集搜索结果的原因) 这是个坏主意吗?在我真正需要它们之前,我宁愿完全禁用它们 我想完全消除HttpSession—我可以在web.xml中这样做吗?我相信有一些特定于容器的方法可以做到这一点 我不这么认为。禁用HttpSession将违反Servlet规范,该规范规定HttpServletRequest#getSession应返回或创建一个会话。所以我不希望J
HttpSession
将违反Servlet规范,该规范规定HttpServletRequest#getSession
应返回或创建一个会话。所以我不希望JavaEE容器提供这样的配置选项(这会使它不兼容)
这是个坏主意吗?在我真正需要它们之前,我宁愿完全禁用它们
嗯,我真的不明白,只是如果你不想使用它,就不要在会话中放任何东西。现在,如果您确实想阻止会话的使用,可以使用过滤器将请求替换为HttpServletRequestWrapper
覆盖getSession()
的实现。但我不会浪费时间来实现这一点:)
更新:我最初的建议不是最佳的,正确的(咳嗽)方法是替换请求。您可以使用URL重写筛选器重写URL,而不是禁用。这将提供谷歌友好的结果,但仍然允许基于cookie的会话处理
然而,您可能应该对所有响应禁用它,因为这比搜索引擎不友好更糟糕。它公开可用于的会话ID
对于Tuckey过滤器:
<outbound-rule encodefirst="true">
<name>Strip URL Session ID's</name>
<from>^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$</from>
<to>$1$2$3</to>
</outbound-rule>
删除URL会话ID
^(.*)(:;jsessionid=[^\?\]*)?(\?[^\\]*)?(\?[^\\]*))?(#*)$
$1$2$3
我想完全消除HttpSession
你不能完全禁用它。您需要做的只是而不是通过request.getSession()
或request.getSession(true)
在Web应用程序代码中的任意位置获取它的句柄,并通过设置
确保JSP不会隐式地这样做
如果您主要关心的是禁用在HttpSession
后台使用的cookie,那么您可以在Java EE 5/Servlet 2.5中仅在特定于服务器的webapp配置中这样做。例如,在Tomcat中,您可以在
元素中将cookies
属性设置为false
<Context cookies="false">
如果要在Web应用程序中硬编码,以便getSession()
永远不会返回HttpSession
(或“空”的HttpSession
),然后,您需要创建一个过滤器,侦听/*
的url模式,该模式将HttpServletRequest
替换为一个返回所有getSession()
方法null
的实现,或者一个不执行任何操作的伪自定义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);
}
这是个坏主意吗?在我真正需要它们之前,我宁愿完全禁用它们
如果你不需要它们,就不要使用它们。这就是全部。真的:)对于RESTful应用程序,我只是在每次请求生命周期结束时使其失效。可能有一些web服务器在新客户端访问时总是创建新会话,无论您是否调用request.getSession()
。我对我的RESTful应用程序使用以下方法来删除任何无意中创建和使用的会话cookie
1.
0
但是,这并不能完全关闭HttpSessions。应用程序仍可能无意中创建会话,即使它在一分钟内消失,并且恶意客户端也可能忽略cookie的最大年龄请求
这种方法的优点是不需要更改应用程序,只需web.xml
。我建议您创建一个HttpSessionListener
,它将记录会话的创建或销毁时间,以便您可以跟踪会话的发生时间。无法避免会话的创建。但是,您可以在请求周期结束时检查您是否违反了自己的要求。因此,创建一个简单的servlet过滤器,将其放在chain的前面和后面。如果创建了会话,doFilter将抛出一个异常:
chain.doFilter(request, response);
if(request.getSession(false) != null)
throw new RuntimeException("Somewhere request.getSession() was called");
如果您正在构建无状态高负载应用程序,您可以禁用使用cookie进行会话跟踪,如下所示(非侵入性,可能与容器无关):
并将其添加到web.xml中,并修复因该异常而失败的位置:
<listener>
<listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class>
</listener>
com.ideas.bucketlist.web.PreventSessionListener
在带有Java配置的Spring Security 3中,您可以使用HttpSecurity.sessionManagement():
Xml看起来像这样
<http create-session="stateless">
<!-- config -->
</http>
顺便说一下,NEVER和无状态的区别
从不:Spring Security不会创建HttpSession,但会使用
HttpSession(如果已存在)将被删除
无状态:Spring安全性永远不会创建HttpSession,而且它会
切勿使用它来获取SecurityContext
从Servlet 3.0开始,您可以通过向ServletContextListener的contextInitialized
方法添加这样的代码,使Servlet容器不会以任何方式跟踪会话:
servletContext.setSessionTrackingModes(Collections.emptySet());
这是一个多么有趣的问题。我遇到的情况是,使用Tomcat时,没有为我创建会话,因此我正在搜索是否有办法在web.xml中打开会话:dthttpservletrequestwrapper听起来不错,我同意。在一个有许多开发人员的大型项目中,您需要执行一些架构决策(比如无状态)。你不能仅仅依靠人们“不使用它”,“如果你不需要他们,就不要使用他们”这并不是那么简单。数百个天秤座中的一些
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");
}
}
<listener>
<listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class>
</listener>
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
<http create-session="stateless">
<!-- config -->
</http>
servletContext.setSessionTrackingModes(Collections.emptySet());