Estoy usando Spring 4.3.5 y WebSocket con SockJS, STOMP y SimpleBrokerMessageHandler.
En mi aplicación, tengo tres extremos de WebSocket separados que se ejecutan en una dirección diferente: /endPointA, /ednpointB, /endpointC Para ser aún más específicos, tengo tres clases de configuración separadas anotadas con anotaciones @Configuration @EnableWebSocketMessageBroker.
También tengo una clase que tiene @Autowired SimpMessagingTemplate.
Finalmente tengo tres clientes, cada uno conectado a un EndPoint diferente. Todos ellos, sin embargo, están suscritos a la "misma" dirección del canal que es /tema/mensajes
Cuando uso SimpMessagingTemplate para enviar algo a /topic/messages , todos los clientes reciben este mensaje.
Después de eso tengo dos preguntas:
Investigué un poco (análisis de volcado de pila) y descubrí que para mi configuración tengo:
Entonces, me pregunto si la propagación de este mensaje en todos los puntos finales es una "característica" de SimpleBrokerMessageHandler o SimpMessagingTemplate.
Me enfrenté al mismo problema en una aplicación multiinquilino que resolví gracias a este hilo :
Mi punto final de websocket es: ws://127.0.0.1/my-context-app/ws , el archivo de configuración de Java es:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").setAllowedOrigins("*"); registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS(); } } Mis formularios de URL de colas de websocket tienen el prefijo de id de inquilino: /[tenant-id]/[url-of-queue] .
Cada cliente se suscribe en su propia identificación de inquilino. No puede suscribirse a la cola de otro cliente gracias al método WebSocketSecurityConfig.configureInbound(MessageSecurityMetadataSourceRegistry) y un spring bean personalizado que tiene un método 'websocket-queue-subscription-security-check':
@Configuration public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer { protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { messages .simpSubscribeDestMatchers("/**") .access("@customWSSecurityCheck.isSubscriptionAllowed(authentication, message)"); } } Mi bean personalizado llamado customWSSecurityCheck verifica si el usuario autenticado puede suscribirse en la cola. Tenga en cuenta que CustomAuthentication implementa org.springframework.security.core.Authentication con un atributo de identificador de inquilino adicional que se completa con un código adicional que no se menciona allí en un método de autenticación/filtro de seguridad Spring personalizado:
@Bean() public class CustomWSSecurityCheck { public boolean isSubscriptionAllowed(CustomAuthentication authentication, Message message) { StompHeaderAccessor sha = StompHeaderAccessor.wrap(message); String url = sha.getDestination().substring(1); String tenantId = url.substring(0, url.indexOf("/")); return tenantId.equals(authentication.getTenantId()); } } Por supuesto, implica que cada mensaje enviado por el servidor debe tener el prefijo del id. de arrendatario correcto: MessagingService.convertAndSend("[tenant-id]/[url-of-queue]", messagePayload)