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

00jrzges  于 2022-11-11  发布在  Spring
关注(0)|答案(2)|浏览(188)

我正在实现一个版本的股票应用程序,其中服务器能够拒绝主题订阅的特定主题的基础上,用户的权利。有没有办法在spring-websocket做到这一点?
例如:
在股票示例项目中,我们有3种商品的价格主题:苹果、微软、谷歌还有两个用户:用户1、用户2
User 1应该可以访问Apple,而Microsoft User 2应该只能访问Google
如果User 1订阅了Google,他应该得到拒绝的响应,并且消息不应该在之后广播给他。

m2xkgtsf

m2xkgtsf1#

感谢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;
    }
}
rta7y2nd

rta7y2nd2#

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

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

相关问题