5

I have a Spring Boot web application that I'm trying to make stateless. In my WebSecurityConfigurerAdapter I have set

    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

But the application (which uses Thymeleaf templates) keeps rewriting URLs for images and scripts by appending ";jsessionid=<some_session_id>" to the file name. In addition to giving me a cookie I don't want, it also has the annoying side effect that Spring Security blocks the request because it has a semicolon in the URL!

Thymeleaf says this is the intended and desired behavior and says it's not their fault: Thymeleaf merely asks the "Servlet API" to rewrite the URL, and that we should "configure the application at the Tomcat context level" to solve the problem.

So, how do I do that? I have a custom JWT cookie for authorization so I don't want or need the session cookie at all, certainly not in rewritten URLs.

workerjoe
  • 2,421
  • 1
  • 26
  • 49
  • In the end I decided to live with the session ID, but neutralize its ability to keep a user logged in outside of my JWT-based authentication, following [this answer to "How can I use Spring Security without sessions"](https://stackoverflow.com/a/7622514/3938965) – workerjoe Mar 05 '20 at 20:23

1 Answers1

7

The jsessionid behavior, has nothing to do with STATELESS.

Initially, the servlet container does not known whether the client (browser) supports cookies, or not.

Therefore, on the first request to the page (typically a HTTP GET):

  1. The servlet container will append the ;jsessionid=... to all URLs.
  2. The servlet container will (try) to set a cookie with the jsessionid.

When clicking on link, or submitting a formular (HTTP GET/POST), the browser will send the cookie back to the server, IF AND ONLY IF, the browser did accept the cookie set in the first place. Now, the servlet container can identify, whether the jsessionid came from the cookie (transmitted via the HTTP Request Header), or the URL.

If the jsessionid originated from the cookie, the servlet container will stop appending the ;jsessionid=... to the URLs. If the jsessionid originated from the URL you clicked, it will continue appending the ;jsessionid= to all URLs.

This has nothing to do with STATELESS or any other configuration of the SessionCreationPolicy.

Take a look at the Spring Security documentation for the SessionCreationPolicy:

/** Always create an {@link HttpSession} */
ALWAYS,
/**
 * Spring Security will never create an {@link HttpSession}, but will use the
 * {@link HttpSession} if it already exists
 */
NEVER,
/** Spring Security will only create an {@link HttpSession} if required */
IF_REQUIRED,
/**
 * Spring Security will never create an {@link HttpSession} and it will never use it
 * to obtain the {@link SecurityContext}
 */
STATELESS

Update:

To disable the tracking mode via URL, set following property:

server.servlet.session.tracking-modes: COOKIE

See: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html

Manuel
  • 3,828
  • 6
  • 33
  • 48