Как отклонить подписку на тему на основе прав пользователя с помощью Spring -websocket

Я реализую версию приложения запаса, где сервер может отклонить подписку на тему для определенной темы на основе прав пользователя. Есть ли способ в spring -websocket для этого?

Например:

В примере с примером на складе у нас есть ценовая тема для 3 инструментов: Apple, Microsoft, Google И есть два пользователя: User1, User2

Пользователь1 должен иметь доступ к Apple и Microsoft Пользователь2 должен иметь доступ только к Google

Если User1 подписаться на Google, он должен получить отклоненный ответ, и сообщение после этого не должно транслироваться.

Ответ 1

Благодаря Rossen Stoyanchev ответ на github Мне удалось решить эту проблему, добавив перехватчик во входящий канал. Изменения, необходимые в демонстрационном приложении spring-websocket-portfolio, следующие:

Измените конфигурацию websocket:

public void configureClientInboundChannel(ChannelRegistration registration) {
    registration.setInterceptors(new TopicSubscriptionInterceptor());
}

И перехватчик был примерно таким:

public class TopicSubscriptionInterceptor extends ChannelInterceptorAdapter {

private static Logger logger = org.slf4j.LoggerFactory.getLogger(TopicSubscriptionInterceptor.class);


@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
    StompHeaderAccessor headerAccessor= StompHeaderAccessor.wrap(message);
    if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand()) {
        Principal userPrincipal = headerAccessor.getUser();
        if(!validateSubscription(userPrincipal, headerAccessor.getDestination()))
        {
            throw new IllegalArgumentException("No permission for this topic");
        }
    }
    return message;
}

private boolean validateSubscription(Principal principal, String topicDestination)
{
    if (principal == null) {
        // unauthenticated user
        return false;
    }
    logger.debug("Validate subscription for {} to topic {}",principal.getName(),topicDestination);
    //Additional validation logic coming here
    return true;
}

}