web-dev-qa-db-fra.com

Cookie HTTP uniquement avec Spring Security et Servlet 2.5?

Je souhaite que mon cookie soit sécurisé et que ma requête http soit la seule.

J'ai vu de nombreux articles comme ceci et semblent bien fonctionner, mais en utilisant des fichiers de configuration et la servlet +3.

Ce que je veux fondamentalement faire est de définir mon cookie http uniquement et (si possible) ssl uniquement.

Jusqu'ici j'ai ajouté ceci à mon web.xml

    <session-config>
        <session-timeout>60</session-timeout>
        <cookie-config>
            <http-only>true</http-only>
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>

ne fait rien, dans la mesure où je lisais, je dois également configurer mon servlet.xml pour activer cette fonctionnalité, mais je ne sais pas comment ...

Une idée comment faire ça?

MODIFIER:

Depuis que j'utilise des servlets 2.5, la configuration XML n'est pas une option, peut-être un filtre?

10
jpganz18

Je déteste la configuration XML, alors je passe du temps à trouver une solution non-XML.

Depuis Spring Security 1.3, vous pouvez utiliser

server.session.cookie.http-only=true
server.session.cookie.secure=true

dans votre application.properties fichier.

Peut-être y a-t-il un moyen de définir cela à l'aide de la configuration Java pure, mais je ne les trouve pas.

4
jakub.josef

Nous avons rencontré ce problème récemment. J'ai essayé les paramètres de propriété pour http uniquement, qui fonctionnaient localement, mais pas lorsque nous avons déployé notre environnement de test. Il est possible que certains paramètres par défaut dans l'environnement remplacent ces paramètres locaux. Ce qui a fonctionné a été de définir les propriétés dans un fichier de configuration Spring:

@Bean
public ServletContextInitializer servletContextInitializer() {
    return new ServletContextInitializer() {
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            servletContext.setSessionTrackingModes(Collections.singleton(SessionTrackingMode.COOKIE));
            SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
            sessionCookieConfig.setHttpOnly(true);
            sessionCookieConfig.setSecure(true);
        }
    };
}
1
Rick Pearce

Les modifications de context.xml mentionnées par javagc ne reconfigureront que le cookie de session.

Pour changer tous vos cookies, vous avez 2 options:

Option 1) Mettez à jour votre code d'application pour ajouter des cookies en utilisant une méthode plus sécurisée. Exemple: https://stackoverflow.com/a/30488471/95674

Option 2) Vous pouvez configurer un filtre de servlet pour modifier TOUS les (autres) cookies provenant du système. Ajoutez ces 2 classes dans le package approprié de votre fichier WAR. Puis mettez à jour votre fichier web.xml comme indiqué ci-dessous.

Si vous souhaitez ajouter une dépendance aux bibliothèques OWASP, un exemple plus simple de l'option 2 est répertorié sur le site OWASP. Cela se trouve ici: https://www.owasp.org/index.php/HttpOnly#Using_Java_to_Set_HttpOnly

Réponse Wrapper

Cela ajoute l'indicateur http uniquement à tous les cookies de la réponse encapsulée.

public class HttpOnlyResponseWrapper extends HttpServletResponseWrapper {

 public HttpOnlyResponseWrapper(HttpServletResponse res) {
   super(res);
 }

 public void addCookie(Cookie cookie) {
   StringBuilder header = new StringBuilder();
   if ((cookie.getName() != null) && (!cookie.getName().equals(""))) {
     header.append(cookie.getName());
   }
   if (cookie.getValue() != null) {
     // Empty values allowed for deleting cookie
     header.append("=" + cookie.getValue());
   }

   if (cookie.getVersion() == 1) {
     header.append(";Version=1");
     if (cookie.getComment() != null) {
       header.append(";Comment=\"" + cookie.getComment() + "\"");
     }
     if (cookie.getMaxAge() > -1) {
       header.append(";Max-Age=" + cookie.getMaxAge());
     }
   } else {
     if (cookie.getMaxAge() > -1) {
       Date now = new Date();
       now.setTime(now.getTime() + (1000L * cookie.getMaxAge()));
       SimpleDateFormat cookieFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz");
       header.append(";Expires=" + cookieFormat.format(now));
     }
   }

   if (cookie.getDomain() != null) {
     header.append(";Domain=" + cookie.getDomain());
   }
   if (cookie.getPath() != null) {
     header.append(";Path=" + cookie.getPath());
   }
   if (cookie.getSecure()) {
     header.append(";Secure");
   }
   header.append(";httpOnly");
   addHeader("Set-Cookie", header.toString());
 }
}

Filtre

Ce filtre englobe les réponses configurées dans le wrapper ci-dessus.

package yourpackage;

@WebFilter(filterName = "HttpOnlyFilter", urlPatterns = {"/*"})
public class HttpOnlyFilter implements Filter {
 private FilterConfig config;

 @Override
 public void destroy() {
   this.config = null;
 }

 @Override
 public void doFilter(ServletRequest req, ServletResponse res,
     FilterChain chain) throws IOException, ServletException {

   HttpOnlyResponseWrapper hres = new HttpOnlyResponseWrapper((HttpServletResponse)res);
   chain.doFilter(req, hres);
 }

 public FilterConfig getFilterConfig() {
   return this.config;
 }

 @Override
 public void init(FilterConfig config) throws ServletException {
   this.config = config;
 }
}

Adapté (ATTENTION: PAS une copie exacte!) De la source: http://sylvanvonstuppe.blogspot.com/2007/07/servlet-filter-for-httponly.html

web.xml

Un dernier détail: UNIQUEMENT SI le contrôle des annotations est désactivé sur votre système, comme suit:

<web-app xmlns="http://Java.Sun.com/xml/ns/javaee"
         version="2.5" ***metadata-complete="true"***>
</web-app> 

Ensuite, vous devrez configurer manuellement le filtre ci-dessus dans votre fichier web.xml, comme ceci:

<filter>
    <filter-name>HttpOnlyFilter
    <filter-class>yourpackage.HttpOnlyFilter
</filter>
<filter-mapping>
    <filter-name>HttpOnlyFilter
    <url-pattern>/*
</filter-mapping>

Si votre application analyse les annotations (qui est la valeur par défaut), la partie web.xml n'est pas nécessaire.

1
Barett

Avec l'aide de ServletContextListener nous contrôlons le servlet au démarrage et à l'arrêt de Tomcat. Donc, ici, au démarrage de Tomcat, nous définissons la configuration de httponly.

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public final class ContextListener implements ServletContextListener {

    private ServletContext context = null;
    @Override
    public void contextDestroyed(ServletContextEvent event) {
        this.context = null;
    }
    @Override
    public void contextInitialized(ServletContextEvent event) {
        this.context = event.getServletContext();
        this.context.getSessionCookieConfig().setHttpOnly(true);

    }
}

Abb ci-dessous entrée dans web.xml

<listener>
<description>contextListener</description>
<listener-class>
        main.ContextListener 
    </listener-class>
 </listener>
0
Dipak Prajapati