你如何在tomcat / java webapps中配置HttpOnly cookie?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you configure HttpOnly cookies in tomcat / java webapps?
提问by ScArcher2
After reading Jeff's blog post on Protecting Your Cookies: HttpOnly. I'd like to implement HttpOnly cookies in my web application.
阅读 Jeff 关于保护您的 Cookie:HttpOnly的博客文章后。我想在我的 Web 应用程序中实现 HttpOnly cookie。
How do you tell tomcat to use http only cookies for sessions?
你如何告诉 tomcat 在会话中只使用 http cookie?
采纳答案by jt.
httpOnly is supported as of Tomcat 6.0.19 and Tomcat 5.5.28.
自 Tomcat 6.0.19 和 Tomcat 5.5.28 起支持 httpOnly。
See the changelogentry for bug 44382.
请参阅错误 44382 的变更日志条目。
The last comment for bug 44382states, "this has been applied to 5.5.x and will be included in 5.5.28 onwards." However, it does not appear that 5.5.28 has been released.
错误44382的最后一条评论指出,“这已应用于5.5.x,并将包含在 5.5.28 之后。” 但是,似乎没有发布 5.5.28。
The httpOnly functionality can be enabled for all webapps in conf/context.xml:
可以为conf/context.xml 中的所有 webapps 启用 httpOnly 功能:
<Context useHttpOnly="true">
...
</Context>
My interpretation is that it also works for an individual context by setting it on the desired Contextentry in conf/server.xml(in the same manner as above).
我的解释是,它也适用于单个上下文,方法是在conf/server.xml 中的所需上下文条目上设置它(以与上面相同的方式)。
回答by Shabaz
For session cookies it doesn't seem to be supported in Tomcat yet. See the bug report Need to add support for HTTPOnly session cookie parameter. A somewhat involved work-around for now can be found here, which basically boils down to manually patching Tomcat. Can't really find an easy way to do it at this moment at this point I'm affraid.
对于会话 cookie,Tomcat 似乎尚不支持它。请参阅错误报告需要添加对 HTTPOnly 会话 cookie 参数的支持。现在可以在这里找到一个有点复杂的解决方法,它基本上归结为手动修补 Tomcat。在这一点上我真的找不到一种简单的方法来做到这一点,我很害怕。
To summarize the work-around, it involves downloading the 5.5 source, and then change the source in the following places:
总结一下解决方法,它涉及下载 5.5源,然后在以下位置更改源:
org.apache.catalina.connector.Request.java
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
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);
}
回答by Cheekysoft
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.
更新:此处的 JSESSIONID 内容仅适用于较旧的容器。请使用 jt 当前接受的答案,除非您使用 < Tomcat 6.0.19 或 < Tomcat 5.5.28 或其他不支持 HttpOnly JSESSIONID cookie 作为配置选项的容器。
When setting cookies in your app, use
在您的应用程序中设置 cookie 时,请使用
response.setHeader( "Set-Cookie", "name=value; HttpOnly");
However, in many webapps, the most important cookie is the session identifier, which is automatically set by the container as the JSESSIONID cookie.
但是,在许多 webapp 中,最重要的 cookie 是会话标识符,它由容器自动设置为 JSESSIONID cookie。
If you only use this cookie, you can write a ServletFilter to re-set the cookies on the way out, forcing JSESSIONID to HttpOnly. The page at http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspxhttp://alexsmolen.com/blog/?p=16suggests adding the following in a filter.
如果只使用这个cookie,可以写一个ServletFilter在出路时重新设置cookie,强制JSESSIONID为HttpOnly。http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspxhttp://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" );
}
but note that this will overwrite all cookies and only set what you state here in this filter.
但请注意,这将覆盖所有 cookie,并且只会设置您在此过滤器中声明的内容。
If you use additional cookies to the JSESSIONID cookie, then you'll need to extend this code to set all the cookies in the filter. This is not a great solution in the case of multiple-cookies, but is a perhaps an acceptable quick-fix for the JSESSIONID-only setup.
如果您对 JSESSIONID cookie 使用其他 cookie,则需要扩展此代码以设置过滤器中的所有 cookie。在多个 cookie 的情况下,这不是一个很好的解决方案,但对于 JSESSIONID-only 设置可能是一个可接受的快速修复。
Please note that as your code evolves over time, there's a nasty hidden bug waiting for you when you forget about this filter and try and set another cookie somewhere else in your code. Of course, it won't get set.
请注意,随着您的代码随着时间的推移而发展,当您忘记此过滤器并尝试在代码中的其他位置设置另一个 cookie 时,会有一个令人讨厌的隐藏错误等着您。当然,它不会被设置。
This really is a hack though. If you do use Tomcat and can compile it, then take a look at Shabaz's excellent suggestion to patch HttpOnly support into Tomcat.
这确实是一个黑客。如果您确实使用 Tomcat 并且可以编译它,那么请查看 Shabaz 的极好建议,将 HttpOnly 支持修补到 Tomcat 中。
回答by Hendrik Brummermann
Please be careful not to overwrite the ";secure" cookie flag in https-sessions. This flag prevents the browser from sending the cookie over an unencrypted http connection, basically rendering the use of https for legit requests pointless.
请注意不要覆盖 https 会话中的 ";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);
}
}
回答by Pete Brumm
also it should be noted that turning on HttpOnly will break applets that require stateful access back to the jvm.
还应该注意的是,打开 HttpOnly 会破坏需要有状态访问回 jvm 的小程序。
the Applet http requests will not use the jsessionid cookie and may get assigned to a different tomcat.
Applet http 请求不会使用 jsessionid cookie,并且可能会被分配给不同的 tomcat。
回答by Jesse Vogt
For cookies that I am explicitly setting, I switched to use SimpleCookieprovided by Apache Shiro. It does not inherit from javax.servlet.http.Cookie so it takes a bit more juggling to get everything to work correctly however it does provide a property set HttpOnly and it works with Servlet 2.5.
对于我明确设置的 cookie,我改用了Apache Shiro提供的SimpleCookie。它不是从 javax.servlet.http.Cookie 继承的,所以它需要更多的杂耍才能使一切正常工作,但是它确实提供了一个属性集 HttpOnly 并且它可以与 Servlet 2.5 一起使用。
For setting a cookie on a response, rather than doing response.addCookie(cookie)
you need to do cookie.saveTo(request, response)
.
要在响应上设置 cookie,而不是这样做,response.addCookie(cookie)
您需要执行cookie.saveTo(request, response)
.
回答by Alireza Fattahi
If your web server supports Serlvet 3.0 spec, like tomcat 7.0+, you can use below in web.xml
as:
如果您的 Web 服务器支持 Serlvet 3.0 规范,例如 tomcat 7.0+,您可以在下面使用web.xml
:
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
As mentioned in docs:
如文档中所述:
HttpOnly: Specifies whether any session tracking cookies created by this web application will be marked as HttpOnly
Secure: Specifies whether any session tracking cookies created by this web application will be marked as secure even if the request that initiated the corresponding session is using plain HTTP instead of HTTPS
HttpOnly:指定此 Web 应用程序创建的任何会话跟踪 cookie 是否将标记为 HttpOnly
Secure:指定即使发起相应会话的请求使用普通 HTTP 而不是 HTTPS,此 Web 应用程序创建的任何会话跟踪 cookie 是否也将标记为安全
Please refer to how to set httponly and session cookie for java web application
回答by Systemsplanet
In Tomcat6, You can conditionally enable from your HTTP Listener Class:
在 Tomcat6 中,您可以有条件地从您的 HTTP 侦听器类启用:
public void contextInitialized(ServletContextEvent event) {
if (Boolean.getBoolean("HTTP_ONLY_SESSION")) HttpOnlyConfig.enable(event);
}
Using this class
使用这个类
import java.lang.reflect.Field;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import org.apache.catalina.core.StandardContext;
public class HttpOnlyConfig
{
public static void enable(ServletContextEvent event)
{
ServletContext servletContext = event.getServletContext();
Field f;
try
{ // WARNING TOMCAT6 SPECIFIC!!
f = servletContext.getClass().getDeclaredField("context");
f.setAccessible(true);
org.apache.catalina.core.ApplicationContext ac = (org.apache.catalina.core.ApplicationContext) f.get(servletContext);
f = ac.getClass().getDeclaredField("context");
f.setAccessible(true);
org.apache.catalina.core.StandardContext sc = (StandardContext) f.get(ac);
sc.setUseHttpOnly(true);
}
catch (Exception e)
{
System.err.print("HttpOnlyConfig cant enable");
e.printStackTrace();
}
}
}