如何使用Spring WebSocket向STOMP客户端发送错误消息?
2022-09-03 15:30:00
我正在使用Spring的STOMP over WebSocket实现,以及一个功能齐全的ActiveMQ代理。当用户访问某个主题时,他们必须通过一些权限逻辑才能成功订阅。我正在使用通道接收器来应用权限逻辑,如下配置:SUBSCRIBE
WebSocketConfig.java:
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableStompBrokerRelay("/topic", "/queue")
.setRelayHost("relayhost.mydomain.com")
.setRelayPort(61613);
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(new MySubscriptionInterceptor());
}
}
WebSocketSecurityConfig.java:
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.simpSubscribeDestMatchers("/stomp/**").authenticated()
.simpSubscribeDestMatchers("/user/queue/errors").authenticated()
.anyMessage().denyAll();
}
}
MySubscriptionInterceptor.java:
public class MySubscriptionInterceptor extends ChannelInterceptorAdapter {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor headerAccessor= StompHeaderAccessor.wrap(message);
Principal principal = headerAccessor.getUser();
if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand())) {
checkPermissions(principal);
}
return message;
}
private void checkPermissions(Principal principal) {
// apply permissions logic
// throw Exception permissions not sufficient
}
}
当没有足够的权限的客户端尝试订阅受限制的主题时,它们实际上从未收到来自该主题的任何消息,但也不会收到有关引发的异常的通知,该异常拒绝了其订阅。相反,客户端会返回一个死订阅,ActiveMQ 代理对此一无所知。(与 STOMP 端点和主题的正常、经过充分许可的客户端交互按预期工作。
我尝试订阅,并在成功连接后使用我的Java测试客户端进行简单操作,但是到目前为止,我无法从交付到客户端的服务器获得有关订阅异常的错误消息。这显然不太理想,因为客户端从未收到过他们被拒绝访问的通知。users/{subscribingUsername}/queue/errors
users/queue/errors