我无法将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>
答案 0 :(得分:2)
我认为问题在于基础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('Set-Cookie', cookie.toString());
答案 1 :(得分:1)
您可以通过TomcatContextCustomizer
配置SameSite:
@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/)中。
答案 2 :(得分:0)
这是使用您自己的CookieSerializer
bean的解决方案。您可以简单地将其添加到您的BootApplication类中:
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setSameSite("None");
return cookieSerializer;
}
但是,这将覆盖默认的spring会话属性,例如相同的会话server.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
属性。我可以想象在将来的春季启动版本中将包含该选项/属性。就像您在TODO代码注释中看到的那样,我没有使用主动的“记住我”服务来测试此解决方案。该解决方案已在春季启动版本2.1.6.RELEASE
中进行了测试,并从org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.class
中的代码中得到启发。
答案 3 :(得分:-1)
LukeSolar的答案是正确的。DefaultCookieSerializer在spring-session
jar中。因此,您需要添加spring-session
依赖项。您可以参考官方文档https://spring.io/projects/spring-session