2013-02-20 44 views
21

有沒有辦法配置Tomcat 7在所有場合使用安全標誌創建JSESSIONID cookie?強制Tomcat使用安全的JSESSIONID Cookie通過http

只有在通過https進行連接時,通常的配置纔會導致Tomcat將會話cookie標記爲帶有安全標誌的會話cookie。但是在我的生產場景中,Tomcat位於反向代理/負載平衡器的後面,該平衡器負責處理(並終止)https連接,並通過http聯繫tomcat。

我可以以某種方式強制會話cookie上的安全標誌與Tomcat,即使通過純http進行連接?

回答

29

最終,出乎我的初步測試,web.xml文件解決方案爲我在Tomcat 7

例如我將這段代碼添加到web.xml中,即使反向代理通過普通HTTP聯繫tomcat,它也會將會話cookie標記爲安全。

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

ServletContext.getSessionCookieConfig()。setSecure(真)

+1

提到由於servlet的3 http://docs.oracle.com/javaee/6/api/javax/servlet/SessionCookieConfig.html – 2014-02-07 21:45:37

1

另一種方法,類似於Mark的,是使用了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" /> 
... 

這使您可以在部署環境的運行時中設置所有會話Cookie配置。因此,您可以使用相同的webapp(war文件)在本地進行開發(您不會使用https),並且在生產中您會希望使用https。

注意,這種方法在OWASP documentation

相關問題