我可以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-pattern
将HttpServletRequest
replace为HttpServletRequestWrapper
实现返回所有getSession()
方法的null
,或者一个虚拟的自定义的HttpSession
实现,它什么也不做,甚至抛出UnsupportedOperationException
exception。
@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");