2013-02-20 4 views
21

Есть ли способ настроить Tomcat 7 для создания JSESSIONID-файла cookie с безопасным флагом во всех случаях?Заставляет Tomcat использовать безопасный файл cookie JSESSIONID по http

Обычные параметры конфигурации в файле cookie с флагом Tomcat с защищенным флагом, только если соединение выполняется через https. Однако в моем сценарии производства Tomcat стоит за обратным прокси/балансиром нагрузки, который обрабатывает (и завершает) соединение https и контакты tomcat через http.

Могу ли я каким-то образом установить безопасный флаг в сеансе cookie с Tomcat, хотя соединение выполняется через простой http?

ответ

29

В конце концов, в отличие от моих первоначальных испытаний, web.xml решение работает для меня на Tomcat 7.

Э.Г. Я добавил этот фрагмент в web.xml и он отмечает, что cookie cookie является безопасным, даже если обратный прокси-сервер связывается с tomcat через простой HTTP.

<session-config> 
    <cookie-config> 
     <http-only>true</http-only> 
     <secure>true</secure> 
    </cookie-config> 
</session-config> 
7

ServletContext.getSessionCookieConfig(). SetSecure (правда)

+1

Так как сервлет 3 http://docs.oracle.com/javaee/6/api/javax/servlet/SessionCookieConfig.html –

1

Другой подход, аналогичный Марк, будет использовать SessionCookieConfig, но установить его в контексте слушателя от конфигурации JNDI:

Код:

import javax.naming.Context; 
import javax.naming.InitialContext; 
import javax.naming.NamingException; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
import javax.servlet.SessionCookieConfig; 


import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 


public class JndiSessionCookieConfigListener implements ServletContextListener { 
    private static final Logger logger = LoggerFactory.getLogger(JndiSessionCookieConfigListener.class); 

    private volatile Context jndiSessionCookieConfig; 
    private volatile SessionCookieConfig sessionCookieConfig; 

    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
     String listenerName = getClass().getSimpleName(); 
     try { 
      logger.info("JNDI override session cookie config found for {}", listenerName); 
      jndiSessionCookieConfig = (Context) new InitialContext().lookup(
        "java:comp/env/" + listenerName); 
     } 
     catch (NamingException e) { 
      logger.info("No JNDI override session cookie config found for {}", listenerName); 
     } 

     sessionCookieConfig = sce.getServletContext().getSessionCookieConfig(); 

     String comment = getString("comment"); 
     if (comment != null) { 
      logger.debug("\t[comment]: [{}]", comment); 
      sessionCookieConfig.setComment(comment); 
     } 

     String domain = getString("domain"); 
     if (domain != null) { 
      logger.debug("\t[domain]: [{}]", domain); 
      sessionCookieConfig.setDomain(domain); 
     } 

     Boolean httpOnly = getBoolean("http-only"); 
     if (httpOnly == null) { 
      sessionCookieConfig.setHttpOnly(true); 
     } 
     else { 
      logger.debug("\t[http-only]: [{}]", httpOnly); 
      sessionCookieConfig.setHttpOnly(httpOnly); 
     } 

     Integer maxAge = getInteger("max-age"); 
     if (maxAge != null) { 
      sessionCookieConfig.setMaxAge(maxAge); 
     } 

     String name = getString("name"); 
     if (name != null) { 
      logger.debug("\t[name]: [{}]", name); 
      sessionCookieConfig.setName(name); 
     } 

     String path = getString("path"); 
     if (path != null) { 
      logger.debug("\t[path]: [{}]", path); 
      sessionCookieConfig.setPath(path); 
     } 

     Boolean secure = getBoolean("secure"); 
     if (secure == null) { 
      sessionCookieConfig.setSecure(true); 
     } 
     else { 
      logger.debug("\t[secure]: [{}]", secure); 
      sessionCookieConfig.setSecure(secure); 
     } 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent sce) { 
    } 

    private Boolean getBoolean(String name) { 
     Object value; 
     try { 
      value = jndiSessionCookieConfig.lookup(name); 
      if (value instanceof Boolean) { 
       return (Boolean)value; 
      } 
      else { 
       return Boolean.valueOf(value.toString()); 
      } 
     } 
     catch (NamingException e) { 
      return null; 
     } 
    } 

    private Integer getInteger(String name) { 
     Object value; 
     try { 
      value = jndiSessionCookieConfig.lookup(name); 
      if (value instanceof Integer) { 
       return (Integer)value; 
      } 
      else { 
       return Integer.valueOf(value.toString()); 
      } 
     } 
     catch (NamingException e) { 
      return null; 
     } 
    } 

    private String getString(String name) { 
     Object value; 
     try { 
      value = jndiSessionCookieConfig.lookup(name); 
      return value.toString(); 
     } 
     catch (NamingException e) { 
      return null; 
     } 
    } 
} 

Внутри web.xml :

... 
    <listener> 
    <listener-class> 
     org.mitre.caasd.servlet.init.JndiSessionCookieConfigListener 
    </listener-class> 
    </listener> 
... 

В вашем context.xml:

... 
<Environment name="JndiSessionCookieConfigListener/secure" 
    type="java.lang.String" 
    override="false" 
    value="true" /> 
... 

Это позволяет установить все конфигурации сеанса печенья во время выполнения в среде развертывания. Таким образом, вы можете использовать один и тот же файл webapp (war file) для локального развития (где у вас не было бы https) и в производстве, где вы бы ALWAYS хотите https.

Обратите внимание, этот подход упоминается в OWASP documentation

Смежные вопросы