'Add secure flag to JSESSIONID cookie in spring automatically

I have a tomcat application server that is behind a nginx. SSL terminates on the nginx. The Spring web-mvc application that is deployed on the tomcat should set the secure flag on the JSESSIONID. It would be cool if spring has some automatic detection for this so I don't get bothered during development because I don't have SSL there.

Is there a way to tell spring to set the flag automatically?

I use JavaConfig to setup the application and use Maven to create a deployable war-file.

I have checked this already, but this looks somehow ugly and static: set 'secure' flag to JSESSION id cookie



Solution 1:[1]

If you are using Spring Boot, there is a simple solution for it. Just set the following property in your application.properties:

server.servlet.session.cookie.secure=true

Source: Spring docs - Appendix A. Common application properties

If you have some environment with HTTPS and some without it, you will need to set it to false in profiles without HTTPS. Otherwise the Secure cookie is ignored.

Solution 2:[2]

in your application.yml just add

server:
  session:
    cookie:
      secure: true

Solution 3:[3]

Behind nginx as ssl terminal point it is not trivial task: secured connection must be detected by nginx header (X-Forwarded-Proto: https, see Using the Forwarded header)
But it is easy solved by nginx config:

if ($scheme = http) {
    return 301 https://$http_host$request_uri;
}
proxy_cookie_path / "/; secure";

Solution 4:[4]

Add another option

You can use a ServletContextInitializer to set secure cookie and http only flag

@Bean
public ServletContextInitializer servletContextInitializer() {
    return new ServletContextInitializer() {
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            servletContext.setSessionTrackingModes(Collections.singleton(SessionTrackingMode.COOKIE));
            SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
            sessionCookieConfig.setHttpOnly(true);
            sessionCookieConfig.setSecure(true);
        }
    };
}

Solution 5:[5]

It's working for me

public class WebInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
    ctx.register(AppConfig.class);
    ctx.setServletContext(servletContext);
    Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
    servlet.addMapping("/");
    servlet.setLoadOnStartup(1);

    servletContext.setSessionTrackingModes(Collections.singleton(SessionTrackingMode.COOKIE));
    SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
    sessionCookieConfig.setHttpOnly(true);
    sessionCookieConfig.setSecure(true);
}
}

Solution 6:[6]

We have a Spring Boot 2.3 app that uses HTTPS to NGINX and HTTP between NGINX and Tomcat.

Even with this Spring property setting:

server:
    servlet:
        session:
            cookie:
                secure: true

... the Secure flag is not being set on the JSESSIONID cookie when the app is accessed via HTTP. You can test this by running the app locally and hitting Tomcat directly using HTTP vs HTTP.

I found that adding this to the config sets the Secure flag for HTTP and HTTPS which fixes our issue when putting NGINX in front of Tomcat using HTTP:

/**
 * Fix for GCP... since we use HTTP internally in Kubernetes, Spring will not make JSESSIONID Secure, but this will.
 *
 * See https://www.javafixing.com/2021/11/fixed-add-secure-flag-to-jsessionid.html
 *
 * @return
 */
@Bean
public ServletContextInitializer servletContextInitializer() {
    return new ServletContextInitializer() {

        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            servletContext.getSessionCookieConfig().setSecure(true);
        }
    };
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 U-ways
Solution 2 AYRM1112013
Solution 3 Grigory Kislin
Solution 4 Khoa Phung
Solution 5 procrastinator
Solution 6 splashout