强制Tomcat通过http使用安全的JSESSIONID cookie

有没有办法在所有场合配置Tomcat 7以创建带有安全标志的JSESSIONID cookie?

只有在通过https建立连接时,通常的配置才会导致Tomcat使用安全标记标记会话cookie。 但是在我的生产场景中,Tomcat是一个反向代理/负载均衡器,它处理(并终止)https连接并通过http联系tomcat。

我可以以某种方式强制使用Tomcat在会话cookie上强制安全标记,即使连接是通过普通的http进行的吗?

最后,与我的初始测试相反,web.xml解决方案在Tomcat 7上为我工作。

例如,我将此片段添加到web.xml,它将会话cookie标记为安全,即使反向代理通过纯HTTP联系tomcat也是如此。

  true true   

ServletContext.getSessionCookieConfig()。setSecure(真)

另一种类似于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里面:

 ...   org.mitre.caasd.servlet.init.JndiSessionCookieConfigListener   ... 

在您的context.xml中:

 ...  ... 

这允许您在部署环境中的运行时设置所有会话cookie配置。 因此,您可以使用相同的webapp(war文件)在本地进行开发(在那里你没有https),在生产中你总是想要https。

注意, OWASP文档中提到了这种方法