如何使用 Spring-websocket 拒绝基于用户权限的主题订阅

Posted

技术标签:

【中文标题】如何使用 Spring-websocket 拒绝基于用户权限的主题订阅【英文标题】:How to reject topic subscription based on user rights with Spring-websocket 【发布时间】:2014-02-28 12:36:21 【问题描述】:

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

例如:

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

User1 应该有权访问 Apple 和 Microsoft User2 应该只能访问 Google

如果用户 1 订阅了谷歌,他应该得到拒绝响应,并且消息不应该广播给他。

【问题讨论】:

【参考方案1】:

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

@Override
public void customizeClientInboundChannel(ChannelRegistration registration) 
    registration.interceptors(new TopicSubscriptionInterceptor());

【讨论】:

【参考方案2】:

感谢 Rossen Stoyanchev answer on 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;

【讨论】:

您好,我正在使用 spring websocket 并面临与您类似的情况。你能告诉我调用 headerAccessor.getHeader("simpUser") 时的值在哪里吗? WebsocketHttpHeaders 只能在客户端为头部添加字符串值。 抛出 org.springframework.messaging.MessagingException 更好

以上是关于如何使用 Spring-websocket 拒绝基于用户权限的主题订阅的主要内容,如果未能解决你的问题,请参考以下文章

spring-webSocket

Spring-websocket 配置 websocket发送消息(群发)

spring-websocket的搭建

Spring-WebSocket服务器环境搭建

Git推送拒绝“非快进”

Spring -websocket实现简易在线聊天