AbstractSecurityWebSocketMessageBrokerConfigurer only one connection per authenticated session - spring

I am using Stomp with Spring Boot and Spring Security. Originally I was using WebSocketMessageBrokerConfigurer and in order to make sure only one connection per authenticated session was allowed I would add ChannelInterceptor in the ConfigureClientInboundChannel override and for the preSend I would check to see if the given authenticated user is already connected and listening.
However I decided to use AbstractSecurityWebSocketMessageBrokerConfigurer because I want to allow only authenticated users to connect to stomp socket.
But it seems that in the AbstractSecurityWebSocketMessageBrokerConfigurer I am not allowed to override ConfigureClientInboundChannel. So since that is the case, how can I check to make sure that on connect, user isn't already connected and listening on some other tab?

Related

How to isolate connection pools per user

I want to have multiple hikari cp connection pools for same database as usual.
Then I would like to isolate these connection pools against specific user logins (which ofcourse by using the user attributes available in http request)
How to dynamically implement this in spring. (I am not having conceptual understanding how spring autoconfiguration handles the incoming requests and assigns the db connection pools)

set InputBufferSize and Timeout of connection for Netty (Reactive Spring) and heartbeats in Reactive WebSocket?

Maybe somebody has experienced this and can help me out.
I have a Reactive WebSocket server (WebFlux Spring Boot).
I checked the connection to the server by Postman and all is good, the connection lasts a long time, but I don't know how long this connection will last with another clients, so I want to set a couple of parameters: InputBufferSize and Timeout, I found how can do it for some servers (Jetty, TomCat,..):
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#websocket-server-runtime-configuration
But I cannot find how can do it for Netty (I use Reactive WebSocket, based on Netty).
How can set InputBufferSize and Timeout of connection for Netty (Reactive Spring)?
And another question is how to send ping-pong (heartbeats), I think I can do it in MyHandler (that implements org.springframework.web.reactive.socket.WebSocketHandler), in
#Override
public Mono handle(WebSocketSession session)
WebSocketMessage has field type (enum: TEXT, BINARY, PING, PONG) I can use it for ping-pong (heartbeats) between any client and my server part. But many forums write that the Netty has already implemented this process (ping-pong) and it will be superfluous - to add it manually in WebSocketHandler. I'm confused here, should I write additional processing (ping-pong in WebSocketHandler) or it will be an unnecessary layer on top of the already made part in Netty?

Spring Session with hazelcast session events firing

I am using Spring Session with Hazelcast and Spring Websockets. As I don't need clustarization I use hazelcast with MapSessionRepository. But it doesn't fire event on session expiring or session deleting. What I want is to listen to SessionExpiredEvent and then disconnect user via websocket immediately. So I have two problems:
MapSessionRepository does not firing needed events (SessionExpiredEvent and etc.)
I don't realize how to send websocket notification using expired http session. I need something like simpMessageTemplate.convertAndSendToUser().
But how I can get the user?
So the only one variant I can see is to write own implementation for SessionRepository<ExpiringSession> with events firing. I hope you understood my question. Thanks in advance.
Spring Session Hazelcast support does provide publishing of session events. The functionality itself is implemented using SessionEntryListener so make sure you use #EnableHazelcastHttpSession annotation which configures all the necessary components for Hazelcast integration.
It might also be of your interest that the upcoming Spring Session 1.3 (currently at 1.3.0.M2) will provide first-class Hazelcast support with new HazelcastSessionRepository (which will, among other things, replace SessionEntryListener).

Spring Websocket Security: How to prevent SEND request directly to the broker

Spring Websocket allows clients (I.e. Browsers) to directly send messages to any broker-backed destination, I.e. Allowing direct client-to-client communication bypassing the server-side application. In real world, I don't think it's acceptable to publicly expose write-access directly to your message broker. For security and message-integrity reason, you'll usually want to allow only the server application to ever send any message to the clients via the broker. But I can't find any information on how to achieve this. The default behaviour is browsers have unrestricted read+write direct access to broker destinations.
This is not technically true, there's no direct communication between the client and the broker, all messages go through your application regardless of the destination type. Broker destination messages are forwarded to the broker, this means you can intercept them at any time before they reach the broker. Spring Security 4.0.0.RC1 has support for WebSocket security so you can apply authorization on your messages:
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.antMatchers(SimpMessageType.MESSAGE, "/topic/**").denyAll()
.antMatchers("/**").hasRole("ADMIN");
}
}
In the above snippet, sending messages to any /topic destination is denied and any other action to other destinations require the role ADMIN. If that's not enough for you, you can always implement your own ChannelInterceptor to intercept messages and add it to the clientInboundChannel.

Detecting disconnects using Spring messaging (websockets / STOMP)

We're using spring-messaging websocket with STOMP. Now we've defined multiple #SubscribeMapping methods, but is there also some sort of callback that gets fired when a client application disconnects from the socket?
We got a list of connect clients and some additional properties, like status. Status field needs to be updated when the client application disconnects.
Any suggestions on how to achieve this in Spring? I've tried implementing ApplicationListener however, there's no usefull information in the OnSessionDisconnect object.

Resources