spring - 在 Spring 中使用 STOMP 和 WebSocket 向特定用户发送消息时检查身份验证

标签 spring websocket stomp spring-messaging

我正在开发一个实时通知系统 Spring 4 通过使用内置 消息代理 , 和 跺脚 超过 WebSocket .

我希望能够根据他的用户名向特定用户发送消息。
为了实现这个目标,我使用了 convertAndSendToUser org.springframework.messaging.simp.SimpMessagingTemplate的方法类,如下:

private final MessagingTemplate messagingTemplate;

@Autowired
public LRTStatusListener(SimpMessagingTemplate messagingTemplate) {
    this.messagingTemplate = messagingTemplate;
}


@Scheduled(fixedDelay=5000)
public void sendMessages(Principal principal)
    messagingTemplate
        .convertAndSendToUser(principal.getName(), "/horray", "Horray, " + principal.getName() + "!");
}

作为配置:
@Configuration
@EnableScheduling
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/notifications").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic", "/queue", "/user");
    }

}

客户端(通过 JavaScript ),我应该通过指定用户名来订阅 channel (根据另一个非常相似的问题: Sending message to specific user on Spring Websocket )。
stompClient.subscribe('/user/' + username + '/horray, ...) 

最后一点听起来很奇怪......

假设我在我的 webapp 上登录为 w.white,通过订阅:
stompClient.subscribe('/user/w.white/horray, ...)

...我将能够看到发送到 w.white 的消息,这太棒了...但是订阅:
stompClient.subscribe('/user/j.pinkman/horray, ...)

...我也将能够看到发送到 j.pinkman 的消息,尽管我目前登录为 w.white。

这是一种克服这个问题的方法吗?

更新

下面是关于通过 WebSocket 进行连接的日志:
Opening Web Socket... 
Web Socket Opened... 
>>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000

<<< CONNECTED
user-name:w.white
heart-beat:0,0
version:1.1

connected to server undefined
Connected: CONNECTED
version:1.1
heart-beat:0,0
user-name:w.white

>>> SUBSCRIBE
id:sub-0
destination:/topic/lrt

>>> SUBSCRIBE
id:sub-1
destination:/user/lrt

最佳答案

我找到了解决方案。

首先,重要的是要知道 /user channel 已由 管理 Spring STOMP ,顺便说一句,不需要注册。

所以:

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
    registry.enableSimpleBroker("/topic", "/queue");
}

然后,我将目标 channel 设置为 /queue/horray :
@Scheduled(fixedDelay=5000)
public void sendMessages(Principal principal)
    messagingTemplate
        .convertAndSendToUser(principal.getName(), "/queue/horray", "Horray, " + principal.getName() + "!");
}

最后,在客户端:
stompClient.subscribe('/user/queue/horray', '...');

现在,它工作正常!根据Principal,消息只发送给指定的收件人。由安全上下文获取。

关于spring - 在 Spring 中使用 STOMP 和 WebSocket 向特定用户发送消息时检查身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25646671/

相关文章:

python - Python回调处理程序-更好的错误消息?

java - 如何在反序列化时重新附加单例 Spring bean

javascript - Spring Maven Angjular JS 问题

java - 无法找到 Spring NamespaceHandler for XML schema 命名空间问题

java - Solr 未找到名称为 [categoryPath] 的方面

mochahost vps 404错误上的Java Websocket聊天

java - flash websocket + jetty

c# - Web 套接字在一段时间后停止响应

activemq - JMSXGroupID/correlation-id 在 stomp 客户端上对消息进行队列似乎不起作用

java - 使用 Spring Rabbitmq Stomp 的持久队列