2010-02-12 52 views
47

我想完全消除HttpSession - 我可以在web.xml中做到這一點嗎?我確定有容器特定的方法來做到這一點(這是搜索結果,當我做一個谷歌搜索)。我可以關閉web.xml中的HttpSession嗎?

P.S.這是一個壞主意嗎?我寧願完全禁用,直到我真正需要它們。

+3

多麼有趣的問題。我有一種情況,在Tomcat中,沒有爲我創建會話,所以我正在尋找是否有辦法在web.xml中打開會話_on_。 :D – Trejkaz 2012-07-31 01:41:18

回答

65

我想消除在HttpSession完全

你不能完全禁用它。您只需要而不是即可通過request.getSession()request.getSession(true)處理您的Web應用程序代碼中的任何位置,並確保您的JSP不會通過設置<%@page session="false"%>隱式執行此操作。

如果您主要關注的是實際禁用在HttpSession後面使用的cookie,那麼您可以在Java EE 5/Servlet 2.5中僅在特定於服務器的webapp配置中執行此操作。例如,在Tomcat中,您可以在<Context>元素中將cookies屬性設置爲false

<Context cookies="false"> 

另請參閱此Tomcat specific documentation。通過這種方式,會話將不會保留在隨後的請求中,這些請求不是URL重寫的 - 只有當您從請求中抓取它時纔出於某種原因。畢竟,如果你不需要它,只是不抓住它,那麼它將不會被創建/保留的。

或者,如果你已經對Java EE 6的/ Servlet的3.0或更高版本,而真正想通過web.xml做到這一點,那麼你可以使用新的<cookie-config>元素web.xml如下爲零時的最大年齡:

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

如果你想在你的web應用進行硬編碼,這樣getSession()從未返回HttpSession(或「空」 HttpSession),那麼你需要創建一個過濾器監聽的/*url-pattern它取代了HttpServletRequestHttpServletRequestWrapper實施,所有012返回種方法null,或虛設定製HttpSession實現這什麼也不做,甚至拋出UnsupportedOperationException

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

附:這是一個壞主意嗎?我寧願完全禁用,直到我真正需要它們。

如果你不需要它們,只是不要使用它們。就這樣。真的:)

+0

@balus ... + 1的一個很好的解釋:) – 2010-02-13 03:40:11

+5

'HttpServletRequestWrapper'聽起來不錯,我會去那。在許多開發人員的大型項目中,您需要執行一些架構決策(如無狀態)。你不能依靠人們「簡單地不使用它」。 – 2012-08-14 17:21:13

+4

_「如果你不需要它們,就不要使用它們」_這並不是那麼簡單。您的項目使用的數百個庫中的一些可能會在某處創建會話。 – 2015-04-29 09:53:43

2

我想完全消除HttpSession - 我可以在web.xml中做到這一點嗎?我敢肯定,有容器具體的方式去做

我不這麼認爲。禁用HttpSession將違反Servlet規範,該規範聲明HttpServletRequest#getSession應返回會話或創建一個會話。所以我不希望Java EE容器提供這樣的配置選項(這會使其不符合規範)。

這是一個壞主意?我寧願完全禁用,直到我真正需要它們。

那麼,我真的不明白這一點,只是如果你不想使用它,就不要在會話中放置任何東西。現在,如果您確實想要阻止使用該會話,則可以使用Filter替換該請求,並將HttpServletRequestWrapper替換爲getSession()。但我不會浪費時間來實現這個:)

更新:我最初的建議是不是最優的,「正確的」(咳嗽)的方法是更換請求。

2

您可以使用URL重寫過濾器例如tuckey rewrite filter來重寫URL,而不是禁用。這會給Google帶來友好的結果,但仍允許基於Cookie的會話處理。

但是,你應該禁用它的所有響應,因爲它更糟糕的不僅僅是搜索引擎不友好。它公開了可用於certain security exploits的會話ID。

Example config爲Tuckey過濾:

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

對於RESTful應用程序,我只是每一個請求的生命週期結束時失效了。無論您是否撥打request.getSession(),新客戶端訪問時都可能有一些Web服務器始終創建新會話。

4

我用下面的方法對我的REST風格的應用程序從創建用於去除任何無意的會話cookie。

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

但是,這並沒有完全關閉HttpSession。會話可能仍然在不經意間的應用程序創建,即使它在一分鐘內消失,惡意的客戶端可能會忽略Cookie的最大年齡要求爲好。

這種方法的優點是你不需要改變你的應用程序,只需web.xml。我建議你創建一個HttpSessionListener,當會話被創建或銷燬時會記錄日誌,以便您可以跟蹤它何時發生。

0

一個無法迴避的會話創建。但是你可以在請求週期結束時檢查你是否違反了你自己的要求。因此,創建一個簡單的Servlet過濾器,你將作爲第一和chain.doFilter後拋出,如果創建會話是一個例外:

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

如果你正在建設一個無狀態的高負載應用程序,您可以禁用使用會話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"); 
} 
} 

並將其添加到網絡。XML和修復的地方,失敗與例外:

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

在Spring Security 3與Java配置,你可以使用HttpSecurity.sessionManagement():

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

XML看起來像這樣;

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

順便說一句,千萬不要和無國籍的區別

NEVER:春季安全永遠不會創建一個HttpSession,但如果它已經存在

無國籍將使用 HttpSession中:春天安全將永遠不會創建一個HttpSession,它將不會使用它來獲取SecurityContext

+0

它不起作用。 – 2017-07-15 13:52:04

+0

@ArtemNovikov你的Spring Security版本是什麼?從3.1開始支持這個未來 – 2017-07-20 14:45:18

相關問題