I'm trying to disable the creation of the JSESSIONID Cookie conditionally.
I only want to create this cookie if a certain cookie in the request is present.
I'm using spring-boot-starter-web 2.5.3 with spring-boot-starter-security.
What I've tried so far
Spring-Session -> CookieSerializer Bean
I tried to add spring-session and define a custom DefaultCookieSerializer-Bean. It turned out that the JSESSIONID is not actually coming from spring, but from the underlying Tomcat.
Using a javax.servlet.Filter which blocks setting the Set-Cookie Header:
package xxxx.configuration;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
@Configuration
public class CookieConsentConfiguration {
private static class CookieConsentFilter implements Filter {
private final ObjectMapper objectMapper;
private CookieConsentFilter(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
final HttpServletRequest req = (HttpServletRequest) request;
if (hasCookieConsent(req)) {
chain.doFilter(request, response);
} else {
chain.doFilter(request, new NoCookiesResponseWrapper((HttpServletResponse) response));
}
}
private boolean hasCookieConsent(HttpServletRequest request) {
try {
final Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("cookie_consent_level")) {
final String value = cookie.getValue();
final JsonNode json = this.objectMapper.readTree(URLDecoder.decode(value, StandardCharsets.US_ASCII));
return json.hasNonNull("strictly-necessary") && json.get("strictly-necessary").booleanValue();
} else if (cookie.getName().equals("cookie_consent_user_accepted")) {
return Boolean.parseBoolean(cookie.getValue());
}
}
}
} catch (Exception e) {
return false;
}
return false;
}
}
private static class NoCookiesResponseWrapper extends HttpServletResponseWrapper {
public NoCookiesResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public void addCookie(Cookie cookie) {
// not allowed
}
@Override
public void setHeader(String name, String value) {
if (!name.equalsIgnoreCase("set-cookie")) {
super.setHeader(name, value);
}
}
@Override
public void addHeader(String name, String value) {
if (!name.equalsIgnoreCase("set-cookie")) {
super.addHeader(name, value);
}
}
}
@Bean
public Filter cookieConsentFilter(ObjectMapper objectMapper) {
return new CookieConsentFilter(objectMapper);
}
}
But this also didn't work. The JSESSIONID is still being created.
Is there any way to disable the creation of this (or any) Cookie if some conditions aren't met?