8

我无法将 SameSite cookie 值设置为无。

以下是我如何生成 ResponseCookie 对象。

ResponseCookie cookie = ResponseCookie.from("Hb", cookieUserId)
            .maxAge(!isEmpty(cookieUserId) ? MAX_COOKIE_DURATION : 0)
            .domain("test.com")
            .sameSite("None")
            .secure(true)
            .path("/")
            .build();
 response.addCookie(cookie)

对端点的卷曲请求

curl -X POST "localhost:8080/v1/user/v" --data "{}" -v -H 'Content-Type: application/json'

回复:

< set-cookie: Hb=00b7be31-fc6d-4891-a07c-46b5ef2b423c; Max-Age=7776000; Expires=Fri, 8 Nov 2019 17:23:52 GMT; Path=/; Domain=test.com; Secure

如您所见,cookie 中缺少 SameSite 属性。

Spring Boot(版本:2.1.3.RELEASE)依赖

        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
4

4 回答 4

7

我认为问题在于底层javax.servlet.http.Cookie不支持SameSite属性,更不用说新None值了。

相反,您可以将其直接设置为标头,假设您的响应是以下实例javax.servlet.http.HttpServletResponse

ResponseCookie cookie = ResponseCookie.from("Hb", cookieUserId)
            .maxAge(!isEmpty(cookieUserId) ? MAX_COOKIE_DURATION : 0)
            .domain("test.com")
            .sameSite("None")
            .secure(true)
            .path("/")
            .build();
 response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
于 2019-08-14T16:37:05.067 回答
2

这是使用您自己的CookieSerializerbean 的解决方案。您可以简单地将其添加到您的 BootApplication 类:

@Bean
public CookieSerializer cookieSerializer() {
    DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
    cookieSerializer.setSameSite("None");
    return cookieSerializer;
}

但是,这将覆盖默认的 spring 会话属性,例如 session sameserver.servlet.session.cookie.name和 maxAge server.servlet.session.cookie.max-age。所以一个更完整的解决方案是这样的:

...
@Autowired
private CookieConfiguration cookieConfiguration;

@Bean
public CookieSerializer cookieSerializer() {
    DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
    cookieSerializer.setSameSite("None");
    cookieSerializer.setCookieName(cookieConfiguration.getName());
    cookieSerializer.setDomainName(cookieConfiguration.getDomain());
    cookieSerializer.setCookiePath(cookieConfiguration.getPath());
    cookieSerializer.setUseHttpOnlyCookie(cookieConfiguration.isHttpOnly());
    cookieSerializer.setUseSecureCookie(cookieConfiguration.isSecure());
    cookieSerializer.setCookieMaxAge((Long.valueOf(cookieConfiguration.getMaxAge().toSeconds())).intValue());
    // TODO check if rememberMeServices need additional configuration here

    return cookieSerializer;
}

和配置类。

@ConfigurationProperties(prefix = "server.servlet.session.cookie")
@Configuration("cookieProperties")
@Getter
@Setter
public class CookieConfiguration {

    private String comment;
    private String domain;
    private boolean httpOnly;
    private Duration maxAge;
    private String name;
    private String path;
    private boolean secure;

}

我不确定是否有更好的解决方案来应用配置属性并且只覆盖samesite属性。我可以想象在未来的 Spring Boot 版本中将包含此选项/属性。此外,正如您在 TODO 代码注释中看到的那样,我没有使用主动记住我的服务来测试这个解决方案。该解决方案在 Spring Boot 版本中进行了测试,2.1.6.RELEASE并从org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.class.

于 2019-08-21T11:37:23.310 回答
2

您可以通过以下方式配置 SameSite TomcatContextCustomizer

@Configuration
public class MvcConfiguration implements WebMvcConfigurer {

  @Bean
  public TomcatContextCustomizer sameSiteCookiesConfig() {
    return context -> {
        final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
        cookieProcessor.setSameSiteCookies(SameSiteCookies.NONE.getValue());
        context.setCookieProcessor(cookieProcessor);
    };
  }

跨站点使用的 Cookie 必须指定SameSite=None; Secure允许包含在第三方上下文中 ( https://web.dev/samesite-cookie-recipes/ )。

于 2020-08-11T13:17:14.360 回答
-1

LukeSolar 的回答是正确的。DefaultCookieSerializer 在 jar 中。spring-session所以你需要添加spring-session依赖项。可以参考官方文档https://spring.io/projects/spring-session

于 2020-05-29T04:22:00.237 回答