使用 SimpleBrokerMessageHandler 时的通信关系 - STOMP Spring
Posted
技术标签:
【中文标题】使用 SimpleBrokerMessageHandler 时的通信关系 - STOMP Spring【英文标题】:Communication relationship when using SimpleBrokerMessageHandler - STOMP Spring 【发布时间】:2014-12-03 15:50:33 【问题描述】:似乎找不到这个问题的答案,也没有足够的关于 SimpleBrokerMessageHandler 的文档。
我沿用了这个例子:https://gerrydevstory.com/2014/03/04/stock-ticker-demo-webapp-using-spring-4-websocket/
如果 client 向 topic 发送消息,则订阅该主题的所有其他客户端都将收到该消息。好像主题的默认关系是many-to-many
。
我希望这种关系是one-to-many
,这意味着一台服务器对许多客户端,而不是许多客户端对许多客户端和服务器。
这种行为表明存在安全/真实性问题 - 按照上面链接中的示例,客户端可以向其他所有人发送虚假股票价格,从而冒充服务器。
我还希望,如果这是这种行为,那么它可能会在 spring websockets 和 stomp 的配置中以某种方式被覆盖或更改,但我无法在任何地方找到足够的信息。
所以问题是:
-
SimpleBrokerMessageHandler 的默认行为真的是
many-to-many
吗?
我是不是没有正确理解topic
的含义?
能否以某种方式改变或控制这种行为?
如果没有,ActiveMQ 或 RabbitMQ 或任何其他第三方代理是否可以满足我的需求(实施one-to-many
方案)?怎么做?
【问题讨论】:
【参考方案1】:带有/topic
前缀的目的地通常是代理目的地,正如您所说的那样,任何人都可以向这些目的地发送消息,并且所有订阅者都会收到这些消息(消息实际上是转发给代理的)。这两种情况都会发生简单代理和代理中继(使用任何成熟的 STOMP 代理,如 RabbitMQ 或 ActiveMQ)。
但是,Spring Security 4(目前在 M2 中)添加了 websocket 安全支持,因此您可以限制发送消息或订阅目的地(请参阅JIRA SEC-2713)。如果这还不够,您可以实现自己的ChannelInterceptor
并将其添加到clientInboundChannel
,以便您可以处理消息并根据您的逻辑将其丢弃。
【讨论】:
非常感谢!我开始认为我做错了什么。由于这将用于生产产品,我不想使用尚未发布的 Spring Security 版本。您对解决方案的其他建议听起来很有趣!您能否提供一些关于我需要在 ChannelIntercetor 代码中检查和执行哪些操作以仅允许一对多关系的信息? 从ChannelInterceptorAdapter
扩展并使用您的逻辑实现 preSend
方法,返回 null 以丢弃消息。另一种选择是创建应用目标 (/app/..),让用户向其发送消息,在控制器中处理消息,然后将结果发送到代理目标以进行广播(请参阅@SendTo
)
好的,谢谢。关于另一个选项,这不会解决真实性问题。我应该在上面的评论中强调这一点。不管怎样,谢谢你的帮助,我会试试的。
当然,这应该与 websocket 安全性一起使用
我使用了你的ChannelInterceptorAdapter
建议,它奏效了!我设法通过覆盖 preSend 函数并在丢弃的消息上返回 null
并在未丢弃时返回 message
来丢弃我不想要的消息。一个重要的注意事项:当为 websockets 使用 XML 配置时,websocket:client-inbound-channel
配置应该在 websocket:simple-broker
和 websocket:stomp-endpoint
之后(如果使用)以上是关于使用 SimpleBrokerMessageHandler 时的通信关系 - STOMP Spring的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)