JAVA应用程序中的SameSite cookie

Mic*_*ulc 23 java cookies flags csrf

你知道任何允许为cookie设置自定义标志的JAVA Cookie实现(比如SameSite = strict)吗?它似乎SameSite=strict有严格限制的标志,可以添加.

kri*_*aex 37

我不是JEE专家,但我认为因为cookie属性是一个有点新的发明,所以你不能指望它出现在Java EE 7接口或实现中.本Cookie类缺少通用性的制定者,因为它似乎.但不是将cookie添加到您的HttpServletResponsevia

response.addCookie(myCookie)
Run Code Online (Sandbox Code Playgroud)

您只需通过设置相应的HTTP标头字段即可

response.setHeader("Set-Cookie", "key=value; HttpOnly; SameSite=strict")
Run Code Online (Sandbox Code Playgroud)

我希望这对你来说已经足够了.

PS:我已根据你的问题删除了我最近的几条评论,也许你也想删除你现在不再需要的3条回复.随后我也可以在这里删除这一段.谢谢.

  • 为什么选择downvote?根据StackOverflow法规,downvotes保留用于质量非常低的邋answer答案,表明缺乏研究工作或知识.在撰写本文时,我是迄今为止唯一一个与OP交谈并寻找解决方法的人,因为他想要的东西目前是不可能的.我甚至解释了为什么它不按照他的意愿行事.即使你不喜欢我的建议,你也不应该贬低它.相反,您可以提供更好的解决方案. (10认同)
  • 请记住,使用“setHeader()”方法将删除所有以前的同名标头,因此我必须执行类似[this](/sf/answers/3549316151/)的操作 (4认同)

nyx*_*yxz 19

如果您碰巧使用 Spring 框架,您可以利用ResponseCookie类。前任:

final ResponseCookie responseCookie = ResponseCookie
        .from("<my-cookie-name>", "<my-cookie-value-here>")
        .secure(true)
        .httpOnly(true)
        .path("/auth")
        .maxAge(12345)
        .sameSite("Lax")
        .build();
response.addHeader(HttpHeaders.SET_COOKIE, responseCookie.toString());
Run Code Online (Sandbox Code Playgroud)

免责声明:标志及其值仅作为类 API 的示例提供。


Mar*_*yan 12

如果您不想更新所有代码,您也可以使用 Apache 或 Nginx 配置(或您正在使用的任何其他 HTTP 服务器/代理)通过一行配置来实现相同的功能

1 使用 Apache 配置设置 SameSite cookie

您可以将以下行添加到您的 Apache 配置中

Header always edit Set-Cookie (.*) "$1; SameSite=Lax"
Run Code Online (Sandbox Code Playgroud)

这将使用SameSite=Lax标志更新您的所有 cookie

在此处查看更多信息:https : //blog.giantgeek.com/?p=1872

2 使用 Nginx 配置设置 SameSite cookie

location / {
    # your usual config ...
    # hack, set all cookies to secure, httponly and samesite (strict or lax)
    proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
}
Run Code Online (Sandbox Code Playgroud)

同样在这里,这也将使用SameSite=Lax标志更新您的所有 cookie

在此处查看更多信息:https : //serverfault.com/questions/849888/add-samesite-to-cookies-using-nginx-as-reverse-proxy


小智 10

截至今天 (24.01.20)servlet-api不允许将sameSite属性设置为 cookie。顺便说一句,有一个正在进行的票证(LINK)将发布一个新的(5.0 或 5.1 servlet-api)。

方案一:不着急,可以等servlet-api版本,Cookie类和SessionCookieConfig类都有专门的方法设置sameSite属性。

选项 2:您使用的是旧版本servlet-api(例如 3.1),因此是旧版本的 Tomcat(例如我现在处于当前情况)。这意味着,即使社会发布servlet-apisameSite支持,系统无法实时更新你的版本,因为它可以是太冒险了更新几个主要的版本。
在这种情况下,我们找到了解决方案。Tomcat里面
有个Cookie Processor ComponentLINK,里面有

CookieProcessor 元素表示将接收到的 cookie 标头解析为可通过 HttpServletRequest.getCookies() 访问的 javax.servlet.http.Cookie 对象并将通过 HttpServletResponse.addCookie() 添加到响应中的 javax.servlet.http.Cookie 对象转换为 HTTP 的组件标头返回给客户端。

该处理器的使用非常简单。在 context.xml 中:

<Context>
    ...
    <CookieProcessor sameSiteCookies="none"/>
</Context>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,使用处理器的默认实现 ( org.apache.tomcat.util.http.Rfc6265CookieProcessor),但您可以在CookieProcessor属性中指定任何其他实现className


小智 6

如果您有现有代码,无疑您已经使用过 java servlet Cookie 对象。我们当然有,所以我们想要破坏性最小的选择。@kriegaex 的回答简洁明了,但基本上是对 cookie 进行硬编码,并且不重用 cookie 对象。为了扩展他的回答,我们编写了这个函数来处理相同的站点功能,同时维护现有的 Cookie 对象功能。此答案旨在用于需要在响应对象上添加多个 cookie 的情况,而无需更改可能已在标头上的现有 cookie。当然,另一种选择是编写一个新的 cookie 类并扩展功能,但这需要对现有代码进行比我们在这里提出的更多更改。

请注意,使用此解决方案,只需更改一行现有代码(每个 cookie)即可添加相同的站点功能。

示例用法:

// Existing code that doesn't change:   
Cookie cookie1=new Cookie("cookie1",Util.encodeURL(id));
cookie1.setHttpOnly(false);
cookie1.setPath("/");

Cookie cookie2=new Cookie("cookie2",Util.encodeURL(id));
cookie2.setHttpOnly(false);
cookie2.setPath("/");

// Old Code that is replaced by new code
// httpResponse.addCookie(cookie1);
// httpResponse.addCookie(cookie2);

// New Code - see static helper class below
HttpService.addCookie(httpResponse, cookie1, "none");
HttpService.addCookie(httpResponse, cookie2, "Strict");
Run Code Online (Sandbox Code Playgroud)

使用 cURL 时的示例响应头:

< HTTP/1.1 200 OK
< Connection: keep-alive
< X-Powered-By: Undertow/1
< Set-Cookie: cookie1=f871c026e8eb418c9c612f0c7fe05b08; path=/; SameSite=none; secure
< Set-Cookie: cookie2=51b405b9487f4487b50c80b32eabcc24; path=/; SameSite=Strict; secure
< Server: WildFly/9
< Transfer-Encoding: chunked
< Content-Type: image/png
< Date: Tue, 10 Mar 2020 01:55:37 GMT
Run Code Online (Sandbox Code Playgroud)

最后,静态助手类:

public class HttpService {
    private static final FastDateFormat expiresDateFormat= FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss zzz", TimeZone.getTimeZone("GMT"));


    public static void addCookie(HttpServletResponse response, Cookie cookie, String sameSite) {

        StringBuilder c = new StringBuilder(64+cookie.getValue().length());

        c.append(cookie.getName());
        c.append('=');
        c.append(cookie.getValue());

        append2cookie(c,"domain",   cookie.getDomain());
        append2cookie(c,"path",     cookie.getPath());
        append2cookie(c,"SameSite", sameSite);

        if (cookie.getSecure()) {
            c.append("; secure");
        }
        if (cookie.isHttpOnly()) {
            c.append("; HttpOnly");
        }
        if (cookie.getMaxAge()>=0) {
            append2cookie(c,"Expires", getExpires(cookie.getMaxAge()));
        }

        response.addHeader("Set-Cookie", c.toString());
    }

    private static String getExpires(int maxAge) {
        if (maxAge<0) {
            return "";
        }
        Calendar expireDate = Calendar.getInstance();
        expireDate.setTime(new Date());
        expireDate.add(Calendar.SECOND,maxAge);

        return expiresDateFormat.format(expireDate);
    }

    private static void append2cookie(StringBuilder cookie, String key, String value) {
        if (key==null || 
                value==null || 
                key.trim().equals("") 
                || value.trim().equals("")) {
            return;
        }

        cookie.append("; ");
        cookie.append(key);
        cookie.append('=');
        cookie.append(value);
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

Jetty 服务器版本9.4.26.v20200117允许SameSite在 cookie 上设置属性。我不得不做一些挖掘,但这有效。

import static org.eclipse.jetty.http.HttpCookie.SAME_SITE_STRICT_COMMENT;

...

Cookie cookie = new Cookie("my-cookie", "some-value");
cookie.setMaxAge(120); // age in seconds
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setComment(SAME_SITE_STRICT_COMMENT);

response.addCookie(cookie);
Run Code Online (Sandbox Code Playgroud)

addCookie()码头服务器对方法Response对象不会对评论进行检查添加的SameSite属性。


var*_*l65 5

我尝试了列出的用于javax.servlet.http.Cookie设置SameSite=strict属性的解决方案,但没有一个有效。

但是,这种方式对我javax.servlet.http.Cookie有用,使用(JRE 1.8 + JBOSS 7.X) :

Cookie cookie = new Cookie(name, value);
path = path.concat("SameSite=Strict;");
cookie.setPath(path);
Run Code Online (Sandbox Code Playgroud)

就是这样。测试

  • Google Chrome 版本 81.0.4044.129(官方版本)(64 位)
  • Microsoft Edge 版本 81.0.416.68(官方版本)(64 位)
  • 火狐 75.0(64 位)

  • 我会将其修改为 ```Cookie cookie = new Cookie(name, value); 路径 = path.concat("; SameSite=Strict;"); cookie.setPath(路径);``` (2认同)