Description
marc schipperheyn opened SPR-14380 and commented
Spring Websocket, basically relies on HTTP Session Cookie based authentication. Custom header tokens, provided when creating a WebSocket are ignored. STOMP login,passcode are also ignored for whatever reason.
After much trial and error and tons and tons of Stackoverflow research, I finally got that Spring WebSocket expects you to create an authenticated session through "normal" website interactions and then use the resulting cookies as an authenticated way to interact with the WebSocket.
So, Spring WebSocket makes the implicit assumption that the WebSocket is created within a webpage where session creation and authentication have basically already taken place through "normal" website interactions. This assumption is what makes Spring WebSocket documentation and examples so confusing.
In a mobile phone scenario. we can get this "normal" website interaction also through a REST endpoint, and then use the resulting cookies to connect with the WebSocket (this suggestion is not documented).
Only, the mobile environment is not such a cut and dried place as the modern web browser is.
Not all Mobile Environments supply cookies through their WebSocket connections. Mine doesn't by default, also not documented by the mobile platform vendor, and I'm still trying to hack my way around that.
I would say that most websocket implementations out there assume header based authentication. It would make life a lot easier. The whole concept of cookies is a browser concept. Headers are much more transparent and clearcut.
So, let me take you through that scenario: getting an existing Spring application to work on websockets.
- You have to integrate Spring Session, Spring Security and Spring WebSocket. All of which are upgrade and implementation challenges by themselves.
- None of the Websocket concepts that you need to understand how this works are clearly documented (101 upgrades, session cookies as the only way to authenticate, etc etc). There are two lines about Authentication in the Spring WebSocket documentation. So, good luck. I would rate Spring's documentation on websockets as 'terrible'. The blog posts and examples as outdated and too simplistic
- The examples and blog posts cover various versions of each library. Some time are even hidden in branches
- Most people don't hit Tomcat directly. Most people use a webserver like nginx in front. It too, needs some specific configuration to deal with 101 upgrades. Good to know.
So, this is just a little list of the issues I ran into. There are issues on all sides: server, webserver, session, security, frontend.
The huge amount of time spent on this stuff could have been significantly reduced if there had been clear documentation on the concepts and assumptions of Spring WebSockets. It would be nice if I knew that step 1 should result in a 101 status. If it doesn't, something is wrong.
Some suggestions:
- Start with a paragraph on how WebSockets work
- First there is a socket request that results in a 101 upgrade
- If you get another status something is wrong
- Differences of creating the websocket (101 upgrade) if you use .withSockJS() or not
- Add a paragraph on how Spring WebSockets work and what it does and doesn't support:
- Assumption of cookie based authentication
- session headers will be ignored
- STOMP username, password will be ignored
- Add a paragraph on Webserver integration
- headers to send back for a 101 upgrade or at least some indication that special configuration is needed for this
- Add a paragraph on integration with Spring Session
- There are tons of session variables floating around in the code. It's not clear why there is a SPRING.SESSION.ID, a SESSION, simpSessionId, etc
- How do sessions work when I get a mobile client that may suffer from network connection loss reconnects?
- Should you use stateless session for mobile phones or not? Pros and Cons?
- What happens if a mobile phone disconnects and reconnects with a session that has expired.
- .i.e. describe some common mobile phone scenarios and how to deal with them.
- Add a paragraph on integration with Spring Security
- Suggestions for debugging
- Check that your webserver is configured to forward 101 to your app server
- Check that the client is sending a session cookie id
- Check that the client is sending a remember me
- Check that the client writes a session and rememberme cookie on "normal" login
- Check that the session cookie path is matching your request (spring session adds an extra slash to a contextpath and spring security does not, it seems)
- [...]
So, this is a bit of a rambling list of suggestions. I hope it's useful nonetheless.
Issue Links:
- Spring WebSockets should support token-based authentication [SPR-14690] #19254 Spring WebSockets should support token-based authentication
2 votes, 7 watchers