javaspringsessiontomcathttps

servletRequest.isSecure() == true but "http".equals(servletRequest.getScheme())


Context: I'm migrating a Spring application 5.3.x hosted on jdk11/tomcat9 to Spring 6.1.x hosted on jdk21/tomcat11

My issue is, after the migration request.isSecure() returns true when I request the Filter in http. Of course prior to the migration, everything was working as expected.

@WebFilter({"/xxx"})
public class MyFilter implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    assert "http".equals(request.getScheme()); // it passes
    assert !request.isSecure(); // it fails
    // create the session here, it will set the JSESSIONID cookie
    request.getSession(true);
    chain.doFilter(request, response);
  }
  
}

It causes the JSESSIONID cookie being set to Secure preventing the browser to send it back on all further requests because I'm accessing the app in http.

enter image description here

Any idea was could cause this issue? Thanks


Solution

  • Tomcat's configuration (e.g. here for Tomcat 9, identical for Tomcat 11) allows you to configure the attribute secure="true" for any connector (Ctrl-f secure).

    This is commonly done when the content is served by a web proxy/tls-terminator, to make tomcat aware that the connection is actually considered to be secure, no matter how it reaches tomcat's connectors.

    Of course, when this is set, Tomcat assumes that everything is good - no matter if you connect through a TLS-terminator/reverse-proxy or directly.

    Full quote from the docs

    Set this attribute to true if you wish to have calls to request.isSecure() to return true for requests received by this Connector. You would want this on an SSL Connector or a non SSL connector that is receiving data from a SSL accelerator, like a crypto card, an SSL appliance or even a webserver. The default value is false.