Glains
Glains

Reputation: 2873

Spring adds a JSESSIONID despite stateless session management

I am using a working JWT authentication of my web application with the following configuration:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      .and()
      .exceptionHandling()
      .authenticationEntryPoint(
          (req, rsp, e) -> p.sendError(HttpServletResponse.SC_UNAUTHORIZED))
      .and()
      .addFilter(new UsernamePasswordAuthenticationFilter(authenticationManager(),
          jwtConfig))
      .addFilterAfter(new JwtTokenAuthenticationFilter(jwtConfig),
          UsernamePasswordAuthenticationFilter.class)
      .authorizeRequests()
      .antMatchers(HttpMethod.POST, jwtConfig.getUri()).permitAll()
      .anyRequest().authenticated();
}

As of SessionCreationPolicy.STATELESS i am expecting that Spring will not create a session itself. However, if i access any other resource than /login, i still see the following entry in the response header:

set-cookie: JSESSIONID=...; Path=/; HttpOnly

Can someone explain where this is coming from (maybe not from Spring) and if it does still come from Spring what needs to be changed?

Edit:

Testing in my controller, the session is still injected as indicated by the above token being present. I still have no clue where this is coming from.

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void create(HttpSession session) {
    if (session != null) {
        System.out.println("Session is existing"); // executes
    }
}

Upvotes: 24

Views: 17649

Answers (6)

veritas
veritas

Reputation: 432

we were using this and it was not working. Apparently it is sensitive to the case and it began to work when used COOKIE instead of cookie

server:
    servlet:
      session:
        tracking-modes: 'COOKIE'
        timeout: 30m

Upvotes: -1

RonyV
RonyV

Reputation: 11

I had the same problem. I discovered that the HttpSession injection creates a session if there isn't already one. So you'll have to get the session yourself and be sure to use the false parameter in the getSession() method. So try this :

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void create() {
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpSession session = attr.getRequest().getSession(false); // do not create one
        if (session == null) {
            LOGGER.warn("Session is null.");
        } else {
            LOGGER.warn("Session id = {}", session.getId());
        }
}

Upvotes: 1

Javanator
Javanator

Reputation: 871

Credit to nils petersohn:

sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER)

Solved this for me in Firefox at least. spring.session.store-type=none in the application.properties did not have any effect.

Upvotes: 1

rougou
rougou

Reputation: 1226

Even with SessionCreationPolicy.STATELESS, a session can still be created outside the scope of spring security. For example, when you call request.getSession() or request.getSession(true), or if you access a session scoped bean (internally spring will call request.getSession(true)).

If you add the following to your application.properties, a stacktrace will be output every time a session is created, which may help you find out what is going on.

logging.level.org.springframework.session.web.http.SessionRepositoryFilter.SESSION_LOGGER=DEBUG

Upvotes: 3

nils petersohn
nils petersohn

Reputation: 2417

Try to set the session to none in the application.yml:

spring.session.store-type=none

as mentioned in the docs: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-session.html

Upvotes: 3

user10367961
user10367961

Reputation:

Your current configuration (sessionCreationPolicy(SessionCreationPolicy.STATELESS)) ensures that Spring-Security (and only Spring-Security)

  • won't create the session
  • won't rely on the session for providing authentication details (for example, providing the Principal).

Any other component of your application (for example, if you would use Spring-Session) is still free to create the session.

Upvotes: 6

Related Questions