Spring безопасность веб-сокетов для нескольких пользователей

Я хочу использовать websocket в весеннем приложении для контактных запросов. У меня уже есть настроенная страница входа для пользователей, и я использую для этого Spring Security. Моя проблема заключается в следующем: как безопасно отправлять сообщения веб-сокетов двум разным пользователям.

Я знаю, что могу транслировать сообщения каждому пользователю, подписанному на какую-либо тему с помощью @SendTo(), и могу транслировать сообщение одному пользователю только с чем-то вроде

messagingTemplate
    .convertAndSendToUser(principal.getName(), "/queue/requests", request);

потому что его имя пользователя хранится в принципале.

Моя проблема заключается в том, как справиться, когда нам нужно настроить таргетинг на 2 пользователей из запроса и сделать его безопасным, чтобы вы не могли просто прослушивать любые каналы со стороны клиента без авторизации.

В идеале я ищу что-то вроде

messagingTemplate
    .convertAndSendToUser(request.getFromUser(), "/queue/requests", request) 

messagingTemplate
    .convertAndSendToUser(request.getToUser(), "/queue/requests", request)

person Bojan Trajkovski    schedule 25.10.2015    source источник
comment
Я думаю, вам нужен Spring Security 4 для этого, а Spring Boot использует Spring Security 3... Spring Security 4.0 представил поддержку авторизации для WebSockets   -  person Neil McGuigan    schedule 27.10.2015


Ответы (2)


Spring WebSocket обрабатывает /пользовательский канал, поэтому я использовал эти методы

Вот как я решил эту проблему:

Когда пользователь аутентифицируется с помощью Spring Security, модуль WebSocket создает уникальный канал для этого пользователя на основе его принципала. Пример "/user/queue/position-updates" переведен на "/queue/position-updates-user123"

Так что на стороне клиента все, что мне нужно было сделать, это подписаться на /user/queue/requests

А на стороне сервера отправьте сообщения /user/{username}/queue/requests с помощью convertAndSendToUser(request.getFromUser(), "/queue/requests", request), а Spring сделает все остальное.

person Bojan Trajkovski    schedule 27.11.2015
comment
вот что я хотел тебе сказать..:) - person MasterCode; 02.12.2015

Вы можете сделать следующее, как указано в Spring-websocket-chat. На стороне клиента вы можете иметь /app/chat.private.{targetUser}

На стороне сервера вы можете получить целевого пользователя, используя @DestinationVariable и исходного пользователя из Principal.

@MessageMapping("/chat.private.{username}")
    public void filterPrivateMessage(@Payload ChatMessage message, @DestinationVariable("username") String username, Principal principal) {
        checkProfanityAndSanitize(message);

        message.setUsername(principal.getName());

        simpMessagingTemplate.convertAndSend("/user/" + username + "/queue/chat.message", message);
    }
person MasterCode    schedule 05.11.2015
comment
Это небезопасно, потому что любой пользователь может подписаться на любой канал. - person Bojan Trajkovski; 27.11.2015
comment
Вы можете добавить безопасность веб-сокета и предоставить доступ к определенному каналу конкретному пользователю с помощью Spring Security - person MasterCode; 27.11.2015
comment
поэтому вы хотите, чтобы два пользователя, получающие сообщение, не авторизовались - person MasterCode; 27.11.2015