我现在正在研究这个问题已有3个星期没有真正的解决方案,我真的希望你能帮助我。
一点项目背景:
使用基于JavaScript / PHP的客户端的Webapp通过SocksJS发送消息并将消息踩到" gate"
门是用Java / Spring编写的,使用@SendTo和@MessageMapping发送和接收消息
来自大门的消息将通过" messageBrokerRegistry.enableStompBrokerRelay"
到目前为止它的工作原理正在发送消息。
现在是高级安全部分:
据我所知,WebSockets本身并不支持安全性。你必须保护你的webapp就像一个普通的" webapp与BASIC auth或类似的东西。所以我添加了一个带有扩展GenericFilterBean的类的servlet过滤器。如果用户发送了正确的cookie页面加载,否则他会收到403错误。
现在问题出现了:
由于@SendTo向所有订阅者发送消息而@SendToUser似乎只将其发送到一个会话,因此我倾向于使用@SendToUser。但似乎无法选择要创建的rabbitMQ队列。我想要一些喜欢" / myqueue-user-123"。这对于@SendToUser是不可能的,因为生成的队列是随机的并且基于SessionID,我无法覆盖。
所以我尝试过(我尝试除了拦截器,事件等之外的其他东西),使用没有值的@SendTo,以便客户端可以决定它必须发送到的队列。
我现在需要评估来自cookie的用户与" / myqueue / user-123"相关联。如果不是,请不要向他发送消息。阻止他订阅。断开他,无论如何。
但在我看来,你绝不可以 - 阻止发送消息,只是"拦截"记录它们不要改变 - 断开websocket,因为它会自动尝试重新连接 - 抛出异常,因为订阅仍然继续(事件只是事件,而不是干扰的东西)。
我会非常感谢任何建议或提示。因为我完全被困在这里......
答案 0 :(得分:2)
我理解你的痛苦,我花了两天时间试图了解有关WebSocket的春季安全问题。
Websocket不要officially
支持一种验证方式,但是,spring-security确实(或多或少)。
我建议您在WebSocket级别进行身份验证,而不是在HTTP,WebSocket(和stomp)的大多数JavaScripts库都不会发送标头以及HTTP握手。
您将找到有关如何在WebSocket级别here进行身份验证的详细指南。在上面的示例中,我使用Websocket Headers值来验证我的客户端,您可以将cookie值放在这些头文件中,或者用localstorage替换cookie。
使用此方法,您可以访问控制器中的Principal
,这可以解决SendToUser问题。