我可以closuresweb.xml中的HttpSession吗?

我想完全消除HttpSession – 我可以在web.xml中做到这一点? 我确定有容器特定的方法来做到这一点(这是search结果,当我做一个谷歌search)。

PS这是一个坏主意? 我宁愿完全禁用,直到我真正需要它们。

我想完全消除HttpSession

你不能完全禁用它。 你只需要在你的web应用代码的任何地方通过request.getSession()或者request.getSession(true)来处理它,并且确保你的JSP不隐式地通过设置<%@page session="false"%>

如果您主要关心的是实际禁用在HttpSession后面使用的cookie,那么您可以在Java EE 5 / Servlet 2.5中仅在特定于服务器的webappconfiguration中进行此操作。 在例如Tomcat中,你可以在<Context>元素中设置cookies属性为false

 <Context cookies="false"> 

另请参阅此Tomcat的特定文档 。 通过这种方式,会话将不会被保留在随后的请求中,这些请求不是URL重写的 – 只有当您由于某种原因从请求中获取请求时才会使用它。 毕竟,如果你不需要它, 只是不抓住它,那么它将不会被创build/保留。

或者,如果您已经使用了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 ),那么你需要创build一个监听/*url-pattern的filter,该url-patternHttpServletRequestreplace为HttpServletRequestWrapper实现返回所有getSession()方法的null ,或者一个虚拟的自定义的HttpSession实现,它什么也不做,甚至抛出UnsupportedOperationExceptionexception。

 @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); } 

PS这是一个坏主意? 我宁愿完全禁用,直到我真正需要它们。

如果你不需要它们,就不要使用它们。 就这样。 真的:)

我使用以下方法为我的REST风格的应用程序删除任何无意的会话cookie被创build使用。

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

但是,这并没有完全closuresHttpSession。 会话仍然可能由应用程序无意中创build,即使它在一分钟内消失,并且stream氓客户端也可能会忽略cookie的最大年龄请求。

这种方法的优点是你不需要改变你的应用程序,只需要web.xml 。 我build议你创build一个HttpSessionListener ,它会在会话创build或销毁时logging日志,以便跟踪它何时发生。

如果你正在构build一个无状态的高负载应用程序,你可以像这样禁用cookies来进行会话跟踪(非侵入式的,可能是容器不可知的):

 <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中,并修复出现该exception的地方:

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

而不是禁用,你可以重写URL使用URL重写filter,例如tuckey重写filter 。 这将给谷歌友好的结果,但仍然允许基于cookie的会话处理。

但是,您应该禁用所有响应,因为它不仅仅是不友好的search引擎。 它暴露了可用于某些安全漏洞的会话ID。

Tuckeyfilter的configuration示例 :

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

我想完全消除HttpSession – 我可以在web.xml中做到这一点? 我确定有容器特定的方法来做到这一点

我不这么认为。 禁用HttpSession将违反Servlet规范,该规范声明HttpServletRequest#getSession应返回会话或创build一个会话。 所以我不希望Java EE容器提供这样的configuration选项(这会使其不符合规范)。

这是一个坏主意吗? 我宁愿完全禁用,直到我真正需要它们。

那么,我真的不明白这一点,如果你不想使用它,就不要在会议中join任何东西。 现在,如果你真的想阻止会话的使用,你可以使用一个Filter来replace请求,用一个HttpServletRequestWrapper实现覆盖getSession() 。 但我不会浪费时间来实现这个:)

更新:我最初的build议不是最佳的,“正确”( 咳嗽 )的方式是取代请求。

对于REST式应用程序,每当请求的生命周期结束时,我都会将其无效化。 无论您调用request.getSession()还是不调用,都可能有一些Web服务器始终会在新客户端访问时创build新会话。

在具有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> 

顺便说一句,从来没有和STATELESS的区别

永远不会:spring安全将永远不会创build一个HttpSession,但将使用HttpSession,如果它已经存在

STATELESS:Spring Security永远不会创build一个HttpSession,它永远不会使用它来获取SecurityContext

一个不能避免创build会话。 但是您可以在请求周期结束时检查是否违反了您自己的要求。 因此,创build一个简单的servletfilter,将其作为第一个放置,然后在链接.doFilter创build会话后抛出exception:

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