I'm building out a Spring 4.2 based, WebSocket + SockJS + STOMP server, and I'd like to be able to get a reference to the WebSocketSession instance using the ws sessionId.
I can create a session manager myself by adding a WebSocketHandlerDecorator that registers new WebSocketSession's as their connections are established (and de-register's on close), but... this seems like something that Spring would already have created in the app context.
Does such a bean/service exist already?
Some background:
My main use case is a security concern. I am performing authorization on a per STOMP message basis, and an unauthorized message should result in the closure of the associated WS. I can intercept the messages and perform authorization, but at the moment I can't get a reference to the WebSocketSession in order to close it.
Second use case; after a successful web socket connection is made, my protocol expects a STOMP CONNECT within X seconds, or again I need to close the underlying WS connection. This one is slightly more interesting since it is asynchronous/timed and doesn't have any natural context like a message interceptor has.
All thoughts and suggestions appreciated.
EDIT
Indeed, Spring's SubProtocolWebSocketHandler class maintains a sessionId to WebSocketSession map, but all access to that map is private.
EDIT
There is support for tracking Users, Sessions, and Subscriptions at the STOMP level. This was added in version 4.2 and isn't documented in the chapter on WebSockets. (It's mentioned as a bullet point under "what's new".)
There is a SimpUserRegistry interface which provides the ability to get a user by name or a set of all users. These are SimpUser instances, which expose access to that user's sessions as a SimpSession either by a session id or as a set of all sessions for that user. From that you can obtain a set of SimpSubscription instances that represent STOMP subscriptions.
Per the javadoc, this should also work in a clustered (relay broker) environment.
Note for future readers, the SimpUserRegistry assumes that you've authenticated a user at the HTTP level, and that said user is defined by the request Principal. If you find yourself with an empty user registry, even though you have good STOMP connections, then you may not be authenticating the way the code wants.
See the last section of authentication under web sockets:
Note that even though the STOMP CONNECT frame has "login" and "passcode" headers that can be used for authentication, Spring’s STOMP WebSocket support ignores them and currently expects users to have been authenticated already via HTTP.
All of the above still preclude access the the underlying web socket session, with it's close() method. I suspect my adoption on WebSocket's is a bit early, and that what I'm seeing is good support at the upper layer protocol (STOMP) level, but less fully fleshed out support for customization at the lower Web Socket layer.
I'm still looking for a way to affect the lower level Web Socket connection based on upper level activity, like non-authorized messages or failure to CONNECT after a TTL.