How to enable samesite for jsessionid cookie

后端 未结 4 1761
时光说笑
时光说笑 2020-12-15 21:32

How can I enable samesite for my web application which runs on wildfly as. Checked standalone.xml however could not find an appropriate tag within



        
4条回答
  •  轮回少年
    2020-12-15 22:24

    As for now the Java Servlet 4.0 specification doesn't support the SameSite cookie attribute. You can see available attributes by opening javax.servlet.http.Cookie java class.

    However, there are a couple of workarounds. You can override Set-Cookie attribute manually.

    The first approach (using Spring's AuthenticationSuccessHandler):

    import java.io.IOException;
    import java.util.Collection;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.http.HttpHeaders;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    
    public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
    
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
            addSameSiteCookieAttribute(response);    // add SameSite=strict to Set-Cookie attribute
            response.sendRedirect("/hello"); // redirect to hello.html after success auth
        }
    
        private void addSameSiteCookieAttribute(HttpServletResponse response) {
            Collection headers = response.getHeaders(HttpHeaders.SET_COOKIE);
            boolean firstHeader = true;
            for (String header : headers) { // there can be multiple Set-Cookie attributes
                if (firstHeader) {
                    response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
                    firstHeader = false;
                    continue;
                }
                response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
            }
        }
    }
    

    The second approach (using javax.servlet.Filter):

    import java.io.IOException;
    import java.util.Collection;
    
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.http.HttpHeaders;
    
    public class SameSiteFilter implements javax.servlet.Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            chain.doFilter(request, response);
            addSameSiteCookieAttribute((HttpServletResponse) response); // add SameSite=strict cookie attribute
        }
    
        private void addSameSiteCookieAttribute(HttpServletResponse response) {
            Collection headers = response.getHeaders(HttpHeaders.SET_COOKIE);
            boolean firstHeader = true;
            for (String header : headers) { // there can be multiple Set-Cookie attributes
                if (firstHeader) {
                    response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
                    firstHeader = false;
                    continue;
                }
                response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
            }
        }
    
        @Override
        public void destroy() {
    
        }
    }
    

    You can look at this demo project on the GitHub for more details on the configuration for org.springframework.security.web.authentication.AuthenticationSuccessHandler or javax.servlet.Filter.

    The WebSecurityConfig contains all the necessary configuration.

    Using addHeader is not guaranteed to work because basically the Servlet container manages the creation of the Session and Cookie. For example, both approaches won't work in case you return JSON in response body because application server will overwrite Set-Cookie header during flushing of response. However, above approaches will work in cases, when you redirect a user to another page after successful authentication.

提交回复
热议问题