Аутентификация пользователя SpringMVC Websockets Messaging с помощью Spring Security
Я видел пару тем об этой проблеме, но ни одна из них, похоже, не отвечает на этот вопрос напрямую.
В фоновом режиме у меня установлена пружинная система безопасности, которая работает и работает в других частях приложения. Мое имя пользователя "разработчик".
Запуск на Java 7, Glassfish 4, Spring 4 и использование Angular + StompJS
Давайте немного кода здесь:
package com.myapp.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer {
public final static String userDestinationPrefix = "/user/";
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp").withSockJS().setSessionCookieNeeded(true);
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
//registry.enableStompBrokerRelay("/topic,/user");
registry.enableSimpleBroker("/topic", "/user");
registry.setUserDestinationPrefix(userDestinationPrefix);
}
}
Хорошо, теперь есть контроллер, который отправляет данные каждые 3 секунды:
import org.springframework.messaging.simp.SimpMessagingTemplate;
…
@Autowired
private SimpMessagingTemplate messagingTemplate;
…
@Scheduled(fixedDelay = 3000)
public void sendStuff ()
{
Map<String, Object> map = new HashMap<>();
map.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
System.out.print("Sending data! " + System.currentTimeMillis());
//messagingTemplate.convertAndSend("/topic/notify", "Public: " + System.currentTimeMillis());
messagingTemplate.convertAndSendToUser("developer", "/notify", "User: " + System.currentTimeMillis());
messagingTemplate.convertAndSendToUser("notYou", "/notify", "Mr Developer Should Not See This: " + System.currentTimeMillis());
}
И, наконец, JavaScript с использованием SockJS
var client = new SockJS('/stomp');
var stomp = Stomp.over(client);
stomp.connect({}, function(s) {
//This should work
stomp.subscribe('/user/' + s.headers['user-name'] + '/notify', console.debug);
//This SHOULD NOT
stomp.subscribe('/user/notYou/notify', console.debug);
});
client.onclose = $scope.reconnect;
И, наконец, для удовольствия, pom.xml
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
Вот что работает:
Я могу прекрасно взаимодействовать между клиентом и серверомЭто быстроmessagingTemplate.convertAndSend
а такжеmessagingTemplate.convertAndSendToUser
Это проблема (отмеченная выше): любой может подписаться на каналы других пользователей.
Теперь, есть несколько других версий этого, я перечислю их ниже, и объясню, почему все ответы неверны:
Каковы проблемы безопасности вокруг открытого соединения через веб-сокет?
Websocket: как отправить сообщение целевому пользователю
Вот проблема:
смотреть наmessagingTemplate.convertAndSendToUser
- Все, что нужно сделать, это добавить «префикс пользователя», а затем предоставленное имя пользователя и затем использоватьmessagingTemplate.convertAndSend
который не относится к безопасности.
Затем люди говорят, что «вам нужно использовать Spring Security, как и везде» - проблема здесь в том, что А) я посылаю данные клиенту асинхронно, поэтому Б) я буду использовать этот код полностью вне сеанса пользователя, возможно от другого пользователя (скажем, чтобы отправить уведомление другому вошедшему в систему пользователю).
Дайте мне знать, если это слишком тесно связано с другим постом, но я это большая проблема для меня, и я хотел сделать это справедливо.
Я могу получить больше деталей, если кому-то нужно больше деталей.