34

我正在实现一个版本的股票应用程序,其中服务器能够根据用户权限拒绝某个主题的主题订阅。spring-websocket 中有没有办法做到这一点?

例如:

在股票示例项目中,我们有 3 个工具的价格主题:Apple、Microsoft、Google 并且有两个用户:User1、User2

User1 应该可以访问 Apple,而 Microsoft User2 应该只能访问 Google

如果 User1 订阅了谷歌,他应该得到拒绝的响应,并且消息不应该在之后广播给他。

4

2 回答 2

57

感谢github 上的 Rossen Stoyanchev 回答, 我设法通过向入站通道添加拦截器来解决这个问题。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;
}

}

于 2014-02-05T14:50:37.517 回答
5

AbstractSecurityWebSocketMessageBrokerConfigurer从 Spring 5.x 开始,如果您正在扩展,则覆盖以附加拦截器的正确方法是customizeClientInboundChannel

@Override
public void customizeClientInboundChannel(ChannelRegistration registration) {
    registration.interceptors(new TopicSubscriptionInterceptor());
}
于 2018-11-05T10:44:23.663 回答