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



我正在为此工作 3 周,但没有真正的解决方案,我真的希望你能帮助我。

一点项目背景:

  • 具有基于 JavaScript/PHP 的客户端的 Web 应用程序通过 SocksJS 发送消息,并将消息发送到"门">

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

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

到目前为止,它工作,正在发送的消息正在返回。

现在是高级安全部分:

  • 消息应通过包含用户和内容的 cookie 进行保护......

据我所知,WebSocket 本身不支持安全性。您必须像使用BASIC身份验证或类似身份验证的"通用"Web应用程序一样保护您的Web应用程序。所以我添加了一个 servlet 过滤器和一个扩展 GenericFilterBean 的类。如果用户发送了正确的cookie,页面加载,否则他会收到403错误。

现在问题来了:

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

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

我现在需要的是评估来自cookie的用户是否与"/myqueue/user-123"相关。如果没有,请不要将消息发送给他。阻止他订阅。断开他的连接,随便。

但在我看来,你绝不能 - 停止发送消息,只需"拦截"即可记录它们而不会更改 - 断开 Websocket 的连接,因为它会自动尝试重新连接 - 抛出异常,因为订阅无论如何都会成功(事件只是事件,而不是要干扰的东西)。

我真的很感激任何建议或提示。因为我完全被困在这里...

我理解你的痛苦,我花了两天时间试图了解有关WebSocket的春季安全混乱。

Websocketofficially不支持身份验证方式,但是,spring-security(或多或少)支持。

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

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

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

最新更新