Spring 4 STOMP在连接时不在标头中发送队列后缀

时间:2014-07-14 16:44:32

标签: spring stomp sockjs spring-4 spring-websocket

我写了一个小项目,它使用带有Websockets的Spring MVC 4和RabbitMQ作为代理。 我试图发送回单个用户(convertAndSendToUser),但我似乎无法让它工作。这是应用程序的作用:

  1. 通过HTTP对Spring Security进行身份验证。身份验证通过AJAX进行,后端为每个新连接分配一个UUID作为用户名。可能有多个客户端具有相同的用户名,因此我希望能够以单个浏览器为目标,尽管他们可能使用相同的用户名登录
  2. 在通过AJAX进行身份验证后,webapp使用STOMP over Websockets连接到API。 这些是在CONNECT FRAME

    中发回的标题

    身体:“” 命令:“已连接” 标题:对象 心跳:“0,0” 服务器:“RabbitMQ / 3.3.1” 会话:“session-OGzAN6T8Y0X9ft3Jq04fiQ” 用户名:“88dc9424-72e3-4814-be8c-e31dbf89b521” 版本:“1.1”

  3. 如您所见,没有框架后缀或会话ID字段。

    1. 当我从后端使用convertAndSendToUser时,响应将发送到一个唯一的队列,如:/ exchange / jobs-userh6g_48h9。队列名称是/ exchange / jobs,但Spring会自动附加后缀 -userh6g_48h9 。用户名是“user”,sessionId是“h6g_48h9”这很好,我想要这个行为,但问题是客户端(webapp)没有在CONNECT框架中获取此会话ID,并且没有办法实际上订阅了那个独特的队列。
    2. 如何解决这个问题?我希望在连接时将队列后缀/会话ID发送回给我,以便客户端可以获得此后缀并订阅其唯一的队列。目前没有消息从服务器返回,因为缺乏信息。

1 个答案:

答案 0 :(得分:0)

如果我错了,请纠正我,但由于UserDestinationMessageHandler,客户端应该能够订阅/user/exchange/jobs,并且该消息处理程序将为您更正队列名称。

作为旁注,您还应该考虑添加一个扩展AbstractSecurityWebSocketMessageBrokerConfigurer的配置类,类似于以下内容:

@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages
                .antMatchers(SimpMessageType.MESSAGE, "/topic/**", "/queue/**").denyAll() // Prevent users sending messages directly to topics and queues
                .antMatchers(SimpMessageType.SUBSCRIBE, "/queue/**/*-user*", "/topic/**/*-user*").denyAll() // Prevent users from subscriptions to private queues
                .antMatchers("/user/queue/errors").permitAll()
                .anyMessage().hasRole("ANY_OPTIONAL_ROLE_ETC")
        ;
    }
}

这将阻止"进取"用户订阅他们不应该做的事情。