2010-02-12 9 views
47

Vorrei eliminare completamente il HttpSession - posso fare questo in web.xml? Sono sicuro che ci sono modi specifici per container per farlo (che è ciò che affolla i risultati della ricerca quando faccio una ricerca su Google).Posso spegnere il HttpSession in web.xml?

P.S. È una cattiva idea? Preferisco disabilitare completamente le cose finché non ne ho davvero bisogno.

+3

Che domanda interessante. Ho una situazione in cui con Tomcat non viene creata alcuna sessione per me, quindi stavo cercando se c'era un modo per trasformare la sessione _on_ in web.xml. : D – Trejkaz

risposta

65

Vorrei eliminare il HttpSession completamente

Non si può del tutto disattivarlo. Tutto quello che devi fare è solo il non per ottenere una maniglia da request.getSession() o request.getSession(true) in qualsiasi punto del codice dell'applicazione web e assicurarti che i tuoi JSP non lo faccia implicitamente impostando <%@page session="false"%>.

Se la vostra preoccupazione principale è in realtà disabilitare il cookie che è stato utilizzato dietro le quinte di HttpSession, allora è possibile in Java EE 5/Servlet 2.5 farlo solo nella configurazione webapp specifica del server. Ad esempio, in Tomcat è possibile impostare l'attributo cookies su false nell'elemento <Context>.

<Context cookies="false"> 

Vedere anche questo Tomcat specific documentation.In questo modo la sessione non verrà conservata nelle richieste successive che non vengono riscritte da URL - solo quando la si cattura dalla richiesta per qualche motivo. Dopo tutto, se non ne hai bisogno, lo solo non lo prendi, quindi non verrà creato/mantenuto affatto.

Oppure, se siete già su Java EE 6/Servlet 3.0 o più recente, e davvero vuole farlo tramite web.xml, quindi è possibile utilizzare il nuovo <cookie-config> elemento web.xml come segue a zero-out l'età massima:

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

Se si vuole hardcode nel vostro webapplication modo che getSession() mai restituisce un HttpSession (o un "vuoto" HttpSession), allora avrete bisogno di creare un filtro in ascolto su un url-pattern di /* che sostituisce la HttpServletRequest con un'implementazione HttpServletRequestWrapper che ritorna su tutto getSession() metodi null o un'implementazione fittizia HttpSession fittizia che non fa nulla, o addirittura genera 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); 
} 

P.S. È una cattiva idea? Preferisco disabilitare completamente le cose finché non ne ho davvero bisogno.

Se non ne hai bisogno, non usarli. È tutto. Davvero :)

+0

@balus ... + 1 per un'ottima spiegazione :) –

+5

Il 'HttpServletRequestWrapper' suona bene, vorrei andare con quello. In un grande progetto con molti sviluppatori è necessario un certo controllo delle decisioni architettoniche (come l'apolidia). Non puoi fare affidamento sulle persone "semplicemente non usando". –

+4

_ "Se non ne hai bisogno, non usarli" _ Non è così semplice. Alcune delle centinaia di librerie utilizzate dal tuo progetto potrebbero creare una sessione da qualche parte. –

2

Vorrei eliminare completamente HttpSession: posso farlo in web.xml? Sono sicuro che ci sono modi specifici del contenitore per farlo

Io non la penso così. La disattivazione del HttpSession sarebbe una violazione delle specifiche Servlet cui si afferma che HttpServletRequest#getSession dovrebbe restituire una sessione o crearne uno. Quindi non mi aspetterei che un contenitore Java EE fornisca tale opzione di configurazione (che lo renderebbe non conforme).

questa è una cattiva idea? Preferisco disabilitare completamente le cose finché non ne ho davvero bisogno.

Beh, non ho proprio capito, non mettere nulla nella sessione se non si vuole usarlo. Ora, se si vuole veramente per impedire l'uso della sessione, è possibile utilizzare un Filter per sostituire la richiesta con un'implementazione di HttpServletRequestWrapper override getSession(). Ma non vorrei perdere tempo l'attuazione del presente :)

Aggiornamento: Il mio suggerimento iniziale non era ottimale, il "diritto" (tosse) modo sarebbe quello di sostituire la richiesta.

2

Invece di disabilitazione è possibile riscrivere l'URL utilizzando un filtro URL riscrittura esempio tuckey rewrite filter. Ciò fornirà risultati amichevoli di Google, ma consentirà comunque la gestione della sessione basata sui cookie.

Tuttavia, dovresti probabilmente disabilitarlo per tutte le risposte poiché è peggio di un semplice motore di ricerca ostile. Espone l'ID di sessione che può essere utilizzato per certain security exploits.

Example config per il filtro Tuckey:

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

Per l'applicazione RESTful, semplicemente lo invalido ogni volta che termina il ciclo di vita della richiesta. Potrebbe esserci qualche server Web che crea sempre nuova sessione quando un nuovo client accede se si chiama request.getSession() o no.

4

Uso il seguente metodo per la mia app RESTful per rimuovere eventuali cookie di sessione involontari da creare e utilizzati.

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

Tuttavia, questo non disattiva completamente HttpSessions. Una sessione può ancora essere creata dall'applicazione inavvertitamente, anche se scompare in un minuto e un client canaglia può ignorare anche la richiesta di età massima per il cookie.

Il vantaggio di questo approccio è che non è necessario modificare l'applicazione, solo web.xml. Ti consigliamo di creare uno HttpSessionListener che effettuerà il log quando viene creata o distrutta una sessione in modo da poter tenere traccia quando si verifica.

0

Non è possibile evitare la creazione della sessione. Ma puoi verificare se violi le tue esigenze alla fine di un ciclo di richieste. Quindi, creare un semplice filtro di servlet, che si posiziona come la prima e dopo chain.doFilter un'eccezione se una sessione è stato creato:

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

Se si sta costruendo un'applicazione carico elevato senza stato è possibile disattivare utilizzando i cookie per la sessione tracciamento come questo (non intrusiva, probabilmente contenitore-agnostico):

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

far rispettare questo architettonica qualcosa decisione di scrittura come questo:

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

E aggiungilo al web.xml e fissare luoghi in cui non riesce con questa eccezione:

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

Nella primavera di sicurezza 3 con Java Config, è possibile utilizzare HttpSecurity.sessionManagement():

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

Xml assomiglia a questo;

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

Tra l'altro, la differenza tra il MAI e STATELESS

MAI: Primavera di sicurezza non potrà mai creare un HttpSession, ma userà HttpSession se esiste già

STATELESS: Primavera La sicurezza non creerà mai una HttpSession e non la utilizzerà mai per ottenere SecurityContext

+0

Non funziona. –

+0

@ArtemNovikov Qual è la tua versione di Spring Security? Questo futuro è supportato dal 3.1 –