web-dev-qa-db-fra.com

Puis-je désactiver la session HTTP dans le fichier web.xml?

Je voudrais éliminer complètement le HttpSession - puis-je le faire dans web.xml? Je suis sûr qu'il existe des méthodes spécifiques pour le conteneur (c'est ce qui encombre les résultats de la recherche lorsque je fais une recherche Google).

P.S. Est-ce une mauvaise idée? Je préfère désactiver complètement les choses jusqu'à ce que j'en aie réellement besoin.

50
les2

Je voudrais éliminer complètement la HttpSession

Vous ne pouvez pas le désactiver complètement. Tout ce que vous avez à faire est de simplement not pour obtenir un identificateur avec request.getSession() ou request.getSession(true) n'importe où dans le code de votre application Web et en vous assurant que vos JSP ne le font pas implicitement en définissant <%@page session="false"%>.

Si votre principale préoccupation est de désactiver le cookie utilisé dans les coulisses de HttpSession, vous pouvez le faire dans Java EE 5/Servlet 2.5 uniquement dans la configuration d'application Web spécifique au serveur. Dans Tomcat, par exemple, vous pouvez définir l'attribut cookies sur false dans l'élément <Context>.

<Context cookies="false">

Voir aussi cette documentation spécifique à Tomcat . De cette façon, la session ne sera pas conservée dans les demandes suivantes qui ne sont pas réécrites d'URL - uniquement lorsque vous la récupérez pour une raison quelconque. Après tout, si vous n'en avez pas besoin, simplement ne le récupérez pas, il ne sera pas créé/conservé du tout.

Ou, si vous utilisez déjà Java EE 6/Servlet 3.0 ou une version plus récente et que vous souhaitez le faire via web.xml, vous pouvez utiliser le nouvel élément <cookie-config> dans web.xml comme suit pour mettre à zéro l'âge maximal:

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

Si vous souhaitez coder en dur dans votre application Web afin que getSession() ne renvoie jamais une HttpSession (ou une "vide" HttpSession), vous devez créer un filtre écoutant un url-pattern de /* qui remplace HttpServletRequest par un HttpServletRequestWrapper implementation qui renvoie toutes les méthodes getSession()null ou une implémentation factice HttpSession qui ne fait rien, ou même jette 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. Est-ce une mauvaise idée? Je préfère désactiver complètement les choses jusqu'à ce que j'en aie réellement besoin.

Si vous n'en avez pas besoin, ne les utilisez pas. C'est tout. Vraiment :)

69
BalusC

Si vous construisez une application sans charge élevée sans charge, vous pouvez désactiver l'utilisation de cookies pour le suivi de session, comme ceci (non intrusif, probablement non lié au conteneur):

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

Pour appliquer cette décision architecturale, écrivez quelque chose comme ceci:

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

Et ajoutez-le à web.xml et corrigez les endroits où il échoue avec cette exception:

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

J'utilise la méthode suivante pour mon application RESTful afin de supprimer la création de cookies de session par inadvertance et.

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

Cependant, cela ne désactive pas complètement les sessions Http. Une session peut toujours être créée par l'application par inadvertance, même si elle disparaît au bout d'une minute et qu'un client non autorisé peut également ignorer la requête max-age pour le cookie.

L'avantage de cette approche est que vous n'avez pas besoin de changer votre application, mais simplement web.xml. Je vous recommanderais de créer une HttpSessionListener qui consignera une session lorsque celle-ci est créée ou détruite afin que vous puissiez suivre son déroulement.

4
Archimedes Trajano

Je voudrais éliminer complètement le HttpSession - puis-je le faire dans web.xml? Je suis sûr qu'il existe des moyens spécifiques pour le conteneur de le faire

Je ne pense pas. La désactivation de HttpSession constituerait une violation de la spécification Servlet qui stipule que HttpServletRequest#getSession doit renvoyer une session ou en créer une. Je ne m'attendrais donc pas à ce qu'un conteneur Java EE fournisse une telle option de configuration (ce qui le rendrait non conforme).

Est-ce une mauvaise idée? Je préfère désactiver complètement les choses jusqu'à ce que j'en aie réellement besoin.

Eh bien, je ne comprends pas vraiment le problème, mais ne mettez rien dans la session si vous ne voulez pas l'utiliser. Maintenant, si vous voulez vraiment empêcher l'utilisation de la session, vous pouvez utiliser un Filter pour remplacer la demande par une implémentation de HttpServletRequestWrapper surchargeant getSession(). Mais je ne perdrais pas de temps à mettre cela en œuvre :)

Mise à jour: Ma suggestion initiale n'était pas optimale, la "bonne" méthode (toux) consisterait à remplacer la demande.

2
Pascal Thivent

Plutôt que de le désactiver, vous pouvez réécrire l'URL en utilisant un filtre de réécriture d'URL, par exemple, le filtre de récriture tuckey . Cela donnera des résultats conviviaux à Google mais permettra toujours la gestion de session basée sur les cookies.

Cependant, vous devriez probablement le désactiver pour toutes les réponses car c'est pire qu'un simple moteur de recherche hostile. Il expose l'ID de session qui peut être utilisé pour certains exploits de sécurité .

Exemple de configuration pour le filtre Tuckey:

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

Dans Spring Security 3 avec Java Config, vous pouvez utiliser HttpSecurity.sessionManagement ():

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

XML ressemble à ceci;

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

À propos, la différence entre NEVER et STATELESS

NEVER: Spring Security ne créera jamais de session HTTP, mais utilisera le HttpSession s'il existe déjà

STATELESS: Spring Security ne créera jamais de session HttpSession et le fera ne l'utilisez jamais pour obtenir le SecurityContext

2
Nicholas Lu

À partir de Servlet 3.0, vous pouvez faire en sorte que les sessions ne soient plus suivies par le conteneur de servlets en ajoutant un code comme celui-ci à la méthode contextInitialized d'une ServletContextListener:

servletContext.setSessionTrackingModes(Collections.emptySet());

Javadoc.

1

Pour une application RESTful, je l'invalide simplement à chaque fois que le cycle de vie de la demande se termine. Il est possible qu'un serveur Web crée toujours une nouvelle session lors d'un nouvel accès client, que vous appeliez request.getSession() ou non.

1
Wittaya

On ne peut pas éviter la création de session. Mais vous pouvez vérifier si vous ne respectez pas vos propres exigences à la fin du cycle de demande. Créez donc un filtre de servlet simple que vous placerez en premier et après chain.doFilter lève une exception si une session a été créée:

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