문제

I'm implementing a version of the stock application where the server able to reject topic subscription for certain topic based on the user rights. Is there a way in spring-websocket to do this?

For example:

In the stock example project we have price topic for 3 instrument: Apple, Microsoft, Google And have two user: User1, User2

User1 should have access to Apple and Microsoft User2 should have access to Google only

If User1 subscribe to Google he should got rejected response, and message shouldn't broadcast to him afterwards.

도움이 되었습니까?

해결책

Thanks to Rossen Stoyanchev answer on github I was manage to solve this by adding interceptor to the inbound channel. Changes needed in the spring-websocket-portfolio demo application is the following:

Change websocket configuration:

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

And the interceptor was something like this:

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;
    }
}

다른 팁

As of Spring 5.x the correct method to override to attach the interceptor, if you're extending AbstractSecurityWebSocketMessageBrokerConfigurer, is customizeClientInboundChannel:

@Override
public void customizeClientInboundChannel(ChannelRegistration registration) {
    registration.interceptors(new TopicSubscriptionInterceptor());
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top