Как правильно реализовать безопасность в сеансе веб-сокета? - PullRequest
0 голосов
/ 13 марта 2020

Я хочу реализовать асинхронный механизм с использованием веб-сокетов. Вот идея:

  1. Клиент выполняет вызов REST
  2. Сервер возвращает «subsingID» и запускает фоновый процесс
  3. Клиент регистрируется как подписчик на этом topi c (предположим, что 12232442 - это идентификатор):

    this.stompClient.subscribe('/callback/12232442', (messageOutput) => {
        let mess = JSON.parse(messageOutput.body);
        console.log(mess);
    });
    
  4. По завершении сервер просто отправляет сообщение и закрывает соединение:

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

Это должно работать, но вот в чем загвоздка: как я могу быть уверен, что другой клиент не может просто подписаться на идентификатор, который существует, но не принадлежит им?

Кроме того, Есть ли встроенный механизм для достижения этого?

1 Ответ

1 голос
/ 15 апреля 2020
  1. Когда сервер получает запрос REST для идентификатора подписки, вы можете сохранить вновь созданный идентификатор в 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.

  }
}

Документация

Обратите внимание, что для этого вам также необходимо хранить сведения об идентификаторе сеанса клиента. Вместо того, чтобы передавать сообщение на /topic/callback/<your_id>, вам необходимо отправить сообщение в пункт назначения следующим образом: /user/queue/callback/<your_id>. Для отправки в пункт назначения как таковой вам необходимо использовать simpMessagingTemplate.convertAndSendToUser(username, destination, payload, Headers) Good Read для этого

Так как вы отправляете сообщения только на определенный сеанс конкретный пользователь, ваши сообщения являются конфиденциальными.

Если вы хотите убедиться, что у вас даже нет подписки от клиента, вы можете отправить клиенту сообщение UNSUBSCRIBE в классе StompEventHandler. Это заставит клиента отказаться от подписки. Хорошо читать для этого

...