【问题标题】:How to correctly implement security on a websocket session?如何在 websocket 会话上正确实现安全性?
【发布时间】:2020-06-25 08:45:52
【问题描述】:

我想使用 websockets 实现一个异步机制。 思路是这样的:

  1. 客户端执行 REST 调用
  2. 服务器返回“subscribingID”并启动后台进程
  3. 客户端注册为本主题的订阅者(假设 12232442 为 id):

    this.stompClient.subscribe('/callback/12232442', (messageOutput) => {
        let mess = JSON.parse(messageOutput.body);
        console.log(mess);
    });
    
  4. 一旦完成,服务器只需发送消息并关闭连接:

    stompSession.send("callback/12232442", new MessageOutput());
    

它应该可以工作,但问题是:我如何确定另一个客户端不能简单地订阅一个存在但不属于他们的 ID?

另外,是否有任何内置机制来实现这一点?

【问题讨论】:

  • 您使用的是什么 STOMP 代理?大多数都内置了用于身份验证和授权的安全机制。
  • 使用spring boot默认代理,然后我用pub/sub向redis集群发送消息

标签: spring-boot websocket stomp


【解决方案1】:
  1. 当服务器收到订阅 ID 的 REST 请求时,您可以将新生成的 ID 存储在订阅 HashMap 中。

  2. 为了在新的订阅请求到来时进行处理,您可以实现自定义StompEventHandler,就像这样

@Controller
public class StompEventHandler{
@EventListener
public void handleSubscription(SessionSubscribeEvent event) {
    //Get incoming sessionDetails from event.
    //get the destination.
    // Validate that the destination is present in Subscription HashMap
    // and also that no client maps to the topic id.
    // Based on the result either send the message or send Unauth message to 
       client.

  }
}

Documentation

  1. 请注意,您还必须为此存储有关客户端会话 ID 的详细信息。您需要将消息发送到目的地,而不是将消息广播到/topic/callback/<your_id>,如下所示:/user/queue/callback/<your_id>。要发送到这样的目的地,您需要使用simpMessagingTemplate.convertAndSendToUser(username, destination, payload, Headers) Good Read for this

  2. 因此,由于您只向特定用户的特定会话发送消息,因此您的消息是机密的。

  3. 如果您想确保您甚至没有来自客户端的订阅,您可以在StompEventHandler 类中向客户端发送UNSUBSCRIBE 消息。这将强制取消订阅客户端。 Good Read for this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-25
    • 2011-02-15
    • 2014-08-08
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2021-05-07
    相关资源
    最近更新 更多