SameSite cookie issue with enabled session persistence

In article SameSite cookie issue in Hybris is described, how to fix issue with SameSite cookie attribute. But, unfortunately, it is not working with enabled session persistence.

With enabled session persistence OOTB Hybris adds JSESSIONID cookie on session persistence on request commit, which means that in previously suggested solution SameSiteCookiePostprocessFilter will not modify cookie, because it would be or missing, or request would be already committed.

To bypass that problem cookie must be changed on request commit, but after session cookie is added. The best option is to reuse same idea as in SaveToSessionResponseWrapper.

The idea is to use OnCommittedResponseWrapper in the first Filter:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.loopintegration.blog.filters;

import com.loopintegration.blog.processor.CookieAttributesPostProcessor;
import org.springframework.security.web.util.OnCommittedResponseWrapper;
import org.springframework.web.filter.GenericFilterBean;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CookiePostprocessFilter extends GenericFilterBean {

    @Resource
    private CookieAttributesPostProcessor cookieAttributesPostProcessor;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if (servletResponse instanceof HttpServletResponse && servletRequest instanceof HttpServletRequest) {
            CookiePostprocessResponseWrapper responseWrapper = new CookiePostprocessResponseWrapper((HttpServletResponse) servletResponse, (HttpServletRequest) servletRequest);

            filterChain.doFilter(servletRequest, responseWrapper);
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    class CookiePostprocessResponseWrapper extends OnCommittedResponseWrapper {

        private final HttpServletRequest request;

        public CookiePostprocessResponseWrapper(HttpServletResponse response, HttpServletRequest request) {
            super(response);
            this.request = request;
        }

        @Override
        protected void onResponseCommitted() {
            ServletResponse response = this.getResponse();
            if (response instanceof HttpServletResponse) {
                appendCookiesMandatoryAttribute((HttpServletResponse) response, this.request);
            }
        }

        protected void appendCookiesMandatoryAttribute(HttpServletResponse response, HttpServletRequest request) {
            cookieAttributesPostProcessor.appendMandatoryAttributes(request, response);
        }
    }

}

With such implementation there is no need changes in GUIDAuthenticationSuccessHandler and no need in SameSiteCookieHandlerInterceptorAdapter at all.

Same as in SameSite cookie issue in Hybris filter must be added at the beginning of filter chain to be executed after session cookie added, but before commit itself.

comments powered by Disqus