保护基于Spring消息传递的websocket服务

我现在正在研究这个问题已有3个星期没有真正的解决方案,我真的希望你能帮助我。

一点项目背景:

  • 使用基于JavaScript / PHP的客户端的Webapp通过SocksJS发送消息并向“门”发送消息

  • 门是用Java / Spring编写的,使用@SendTo和@MessageMapping来发送和接收消息

  • 来自门的消息被发送到RabbitMQ并通过“messageBrokerRegistry.enableStompBrokerRelay”返回给客户端

到目前为止它的工作原理,发送的消息都会回来。

现在是高级安全部分:

  • 消息应该通过包含用户和东西的cookie来保护……

据我所知,WebSockets本身并不支持安全性。 您必须像使用BASIC auth或类似的“常用”webapp一样保护您的webapp。 所以我添加了一个servletfilter,其中包含一个扩展GenericFilterBean的类。 如果用户发送了正确的cookie页面加载,否则他会收到403错误。

现在出现了问题:

由于@SendTo向所有订阅者发送消息而@SendToUser似乎只将其发送到一个会话,因此我倾向于使用@SendToUser。 但似乎无法选择要创建的rabbitMQ队列。 我想要一些像“/ myqueue-user-123”。 @SendToUser无法做到这一点,因为生成的队列是随机的,并且基于SessionID,我无法覆盖。

所以我尝试过(我尝试除了拦截器,事件等之外的其他东西),使用@SendTo没有值,以便客户端可以决定它必须发送到的队列。

我现在需要的是评估cookie中的用户与“/ myqueue / user-123”相关联。 如果不是,请不要向他发送消息。 阻止他订阅。 断开他,无论如何。

但在我看来,你绝对不能 – 阻止发送消息,只是“拦截”以记录它们而不是改变 – 断开websocket因为它自动尝试重新连接 – 抛出exception,因为订阅仍然继续(事件只是事件,不是要干涉的东西)。

我会非常感谢任何建议或提示。 因为我完全被困在这里……

我理解你的痛苦,我花了两天时间试图了解有关WebSocket的Spring安全问题。

Websocket不officially支持一种认证方式,但是,spring-security确实(或多或少)。

我建议您在WebSocket级别进行身份validation,而不是在HTTP上进行身份validation,WebSocket(和stomp)的大多数JavaScripts库都不会随HTTP握手一起发送标头。

您将在此处找到有关如何在WebSocket级别进行身份validation的详细指南。 在上面的示例中,我使用Websocket Headers值来validation我的客户端,您可以将cookie值放在这些头中,或者用localstorage替换cookie。

使用此方法,您可以访问控制器中的Principal ,这应解决SendToUser问题。