Describe the bug

Websocket traffic is not considered as session activity. If an application has active websocket traffic, but infrequent or no HTTP traffic, the websocket will still be terminated anyway.

This seems to happen after server.servlet.session.timeout * 2.

This question on StackOverflow shares the same problem. It has 3000 views, so clearly this behaviour is tripping people up, even if it's not a bug.

In our application, we send a few HTTP requests, establish a websocket, and then all future requests go via the websocket. This behaviour means we need to send what would otherwise be redundant HTTP requests as a keep-alive.

This is reproducible on the latest version of Spring Boot (currently 2.3.3.RELEASE)

To Reproduce

  1. Authorize via HTTP
  2. Establish a websocket
  3. Create ongoing activity back and forth on the websocket
  4. Wait until server.servlet.session.timeout is exceeded (in practice, seems more like 2x this number)

The websocket is disconnected, despite having active traffic

See example https://github.com/michaelboyles/spring-ws-disconnect

Expected behavior

Websocket traffic is treated as session activity. If messages are being exchanged back and forth on the websocket, it will not be closed.

Sample

https://github.com/michaelboyles/spring-ws-disconnect

The readme contains steps required to build and run it.


If it's determine that this is expected behaviour then I feel an acceptable compromise would be for this to be made explicit in the documentation.

Comment From: jzheaux

@michaelboyles, thanks for reaching out.

Spring Security doesn't manage your session, so I don't think that there is much it can do along these lines.

However, Spring Session does have WebSocket support. Have you already taken a look?

For some background, Rob also posted some of the rationale for Spring Session supporting Web Sockets instead of Spring Security.

Regarding documentation, is there something in the documentation that led you to believe that Spring Security would manage the session? If so, perhaps that's the documentation that should be changed.

Comment From: michaelboyles

Thanks a lot for the thorough reply. It seems those links are exactly what I need.

The reason I thought Spring Security was responsible was because if I remove the starter and configuration from this project, the issue disappears. Looking into it a bit more, it seems more like Spring Sec is just responsible for setting up a session on the underlying web container, Tomcat in this case. Is that right?

This seems relevant

Later the SecurityContextPersistenceFilter saves the SecurityContext to the HttpSession.

Now that you've given me a nudge, I'd say the documentation is explicit enough. If I'm nitpicking, maybe a high-level description of how the sessions are managed, as a part of the overview, wouldn't go amiss.

I'll post an answer on that Stack Overflow question with the info you've given me, hopefully that'll be enough to satisfy any future googlers. Or if you have time and think you can do that more comprehensively than me, please feel free.

Happy for you to close this

Comment From: jzheaux

Sounds good, @michaelboyles, glad I could help.

it seems more like Spring Sec is just responsible for setting up a session on the underlying web container, Tomcat in this case. Is that right?

It's probably more correct to say that Spring Security is responsible for managing the SecurityContext. There are several cases when Spring Security will do that using HttpSession.

Unless you configure your application to use Spring Session, then yes it would be Tomcat by default that would be responsible for managing the session.

Or if you have time and think you can do that more comprehensively than me, please feel free.

I look forward to reading your Stack Overflow response! Thanks for taking the time.