Я пытаюсь условно отключить создание файла cookie JSESSIONID
.
Я хочу создать этот файл cookie, только если в запросе присутствует определенный файл cookie.
Я использую spring-boot-starter-web
2.5.3
с spring-boot-starter-security
.
Что я уже пробовал
Spring-Session -> Компонент CookieSerializer
Я попытался добавить spring-session
и определить пользовательский DefaultCookieSerializer
-Bean. Оказалось, что JSESSIONID
на самом деле исходит не от весны, а от нижележащего Tomcat.
Использование javax.servlet.Filter
, которое блокирует настройку заголовка Set-Cookie
:
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);
}
}
Но и это не сработало. JSESSIONID
все еще создается.
Есть ли способ отключить создание этого (или любого) файла cookie, если некоторые условия не выполняются?
Если вы используете сеансы по какой-либо уважительной причине (например, для входа в систему), файл cookie сеанса является наиболее строго необходимым из всех.
Я знаю, и у меня есть логин. А вот Session-Cookie создается сразу при первом посещении страницы, вообще без попытки авторизации. Кроме того, я установил для SessionCreationPolicy значение IF_REQUIRED. Запоминаются ли значения CSRF на стороне сервера при использовании сеанса? Может ли это быть причиной создания сеанса?
По умолчанию используется
LazyCsrfTokenRepository
(см. этот вопрос), поэтому сеанс не создается, если вы используете токен. Можете ли вы привести минимальный пример страницы, которая вызывает проблемы?Да, это была проблема. Я использовал токен
csrf
в каждом из моих шаблонов тимелеафа. Это заставило сеанс быть созданным@Felix: можешь написать ответ на свой вопрос?