如何在tomcat / java webapps中配置HttpOnly cookie?
阅读Jeff关于保护Cookie的博客文章:HttpOnly。我想在我的Web应用程序中实现HttpOnly cookie。
我们如何告诉tomcat在会话中仅使用http cookie?
解决方案
回答
对于会话cookie,Tomcat似乎尚不支持它。请参阅错误报告。需要添加对HTTPOnly会话cookie参数的支持。现在可以在这里找到一些涉及的解决方法,基本上可以归结为手动修补Tomcat。目前,我感到非常震惊,目前还无法找到一种简单的方法。
总结一下解决方法,它涉及下载5.5源,然后在以下位置更改源:
org.apache.catalina.connector.Request.java
//this is what needs to be changed //response.addCookieInternal(cookie); //this is whats new response.addCookieInternal(cookie, true); }
org.apache.catalina.connectorResponse.addCookieInternal
public void addCookieInternal(final Cookie cookie) { addCookieInternal(cookie, false); } public void addCookieInternal(final Cookie cookie, boolean HTTPOnly) { if (isCommitted()) return; final StringBuffer sb = new StringBuffer(); //web application code can receive a IllegalArgumentException //from the appendCookieValue invokation if (SecurityUtil.isPackageProtectionEnabled()) { AccessController.doPrivileged(new PrivilegedAction() { public Object run(){ ServerCookie.appendCookieValue (sb, cookie.getVersion(), cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getDomain(), cookie.getComment(), cookie.getMaxAge(), cookie.getSecure()); return null; } }); } else { ServerCookie.appendCookieValue (sb, cookie.getVersion(), cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getDomain(), cookie.getComment(), cookie.getMaxAge(), cookie.getSecure()); } //of course, we really need to modify ServerCookie //but this is the general idea if (HTTPOnly) { sb.append("; HttpOnly"); } //if we reached here, no exception, cookie is valid // the header name is Set-Cookie for both "old" and v.1 ( RFC2109 ) // RFC2965 is not supported by browsers and the Servlet spec // asks for 2109. addHeader("Set-Cookie", sb.toString()); cookies.add(cookie); }
回答
Update: The JSESSIONID stuff here is only for older containers. Please use jt's currently accepted answer unless you are using < Tomcat 6.0.19 or < Tomcat 5.5.28 or another container that does not support HttpOnly JSESSIONID cookies as a config option.
在应用中设置Cookie时,请使用
response.setHeader( "Set-Cookie", "name=value; HttpOnly");
但是,在许多Web应用程序中,最重要的cookie是会话标识符,会话标识符由容器自动设置为JSESSIONID cookie。
如果仅使用此cookie,则可以编写ServletFilter以便在出局时重新设置cookie,从而将JSESSIONID强制为HttpOnly。 http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx上的页面http://alexsmolen.com/blog/?p=16建议在过滤器中添加以下内容。
if (response.containsHeader( "SET-COOKIE" )) { String sessionid = request.getSession().getId(); response.setHeader( "SET-COOKIE", "JSESSIONID=" + sessionid + ";Path=/<whatever>; Secure; HttpOnly" ); }
但是请注意,这将覆盖所有cookie,并且只会在此过滤器中设置我们在此处声明的内容。
如果在JSESSIONID cookie中使用其他cookie,则需要扩展此代码以在过滤器中设置所有cookie。对于多个cookie,这不是一个很好的解决方案,但是对于仅JSESSIONID的设置来说,这可能是一个可接受的快速修复方法。
请注意,随着代码的不断发展,当我们忘记此过滤器并尝试在代码中的其他位置设置另一个Cookie时,会有一个令人讨厌的隐藏错误等待着我们。当然,它不会被设置。
这确实是一个hack。如果我们确实使用了Tomcat并且可以对其进行编译,那么请看一下Shabaz关于将HttpOnly支持修补到Tomcat中的出色建议。
回答
从Tomcat 6.0.19和Tomcat 5.5.28开始支持httpOnly。
请参阅更改日志条目以获取错误44382.
错误44382的最后一条评论指出:"此错误已应用于5.5.x,并将包含在5.5.28及更高版本中。"但是,似乎没有发布5.5.28.
可以在conf / context.xml中为所有Web应用程序启用httpOnly功能:
<Context useHttpOnly="true"> ... </Context>
我的解释是,通过将其设置在conf / server.xml中所需的Context条目上,它也适用于单个上下文(与上述方法相同)。
回答
请注意不要覆盖https-sessions中的"; secure" cookie标志。此标志可防止浏览器通过未加密的http连接发送cookie,从而使合法请求的https毫无意义地呈现出来。
private void rewriteCookieToHeader(HttpServletRequest request, HttpServletResponse response) { if (response.containsHeader("SET-COOKIE")) { String sessionid = request.getSession().getId(); String contextPath = request.getContextPath(); String secure = ""; if (request.isSecure()) { secure = "; Secure"; } response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionid + "; Path=" + contextPath + "; HttpOnly" + secure); } }
回答
还应该注意的是,打开HttpOnly将破坏需要状态访问jvm的applet。
Applet http请求将不会使用jsessionid cookie,并且可能会分配给其他tomcat。