Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何自定义spring messaging WebSocket用户订阅?_Java_Spring_Spring Security_Spring Websocket_Spring Messaging - Fatal编程技术网

Java 如何自定义spring messaging WebSocket用户订阅?

Java 如何自定义spring messaging WebSocket用户订阅?,java,spring,spring-security,spring-websocket,spring-messaging,Java,Spring,Spring Security,Spring Websocket,Spring Messaging,我在公司环境中使用。spring消息传递组件在DMZ中运行。它通过防火墙连接到ActiveMQ代理网络,进入内部网络。连接在DMZ中使用spring security进行身份验证,并且用户主体可用 我需要订阅特定于用户的主题,内部网络中的服务可以通过与ActiveMQ的连接发布到这些主题。spring消息/user前缀似乎提供了此功能 开箱即用,如果我通过身份验证并订阅了/user/foo/bar主题,则DefaultUserDestinationResolver将其转换为会话id,并且在Act

我在公司环境中使用。spring消息传递组件在DMZ中运行。它通过防火墙连接到ActiveMQ代理网络,进入内部网络。连接在DMZ中使用spring security进行身份验证,并且用户主体可用

我需要订阅特定于用户的主题,内部网络中的服务可以通过与ActiveMQ的连接发布到这些主题。spring消息
/user
前缀似乎提供了此功能

开箱即用,如果我通过身份验证并订阅了
/user/foo/bar
主题,则
DefaultUserDestinationResolver
将其转换为会话id,并且在ActiveMQ中,我看到STOMP连接器订阅了
/foo/bar-userjf44st89
主题。在我的场景中有两个问题

  • 会话id
    jf44st89
    无法转换回用户id,因此内部网络中的服务无法通过其ActiveMQ连接发布给特定用户。它们不是,也永远不会是,从内部网络通过防火墙到DMZ(spring消息传递组件在DMZ中运行)的允许路由,因此任何涉及发布到spring消息传递组件的解决方案都将失效

  • 似乎没有什么可以阻止经过身份验证但未经授权的用户尝试猜测会话id并订阅主题,如
    /foo/bar-userjf44st89
    。不太可能成功,但我宁愿不可能也不要不可能

  • 因此,我想用我自己的bean来增强
    DefaultUserDestinationResolver
    ,它将创建
    /user/user id/session id/foo/bar
    形式的订阅,这将解决这两个问题,并允许内部服务使用ActiveMQ
    *
    通配符来忽略会话id路径组件


    我的主要问题是如何最好地替换
    DefaultUserDestinationResolver
    ?它是由
    AbstractMessageBrokerConfiguration
    类作为bean创建的。用户创建自己的
    @Primary
    UserDestinationResolver bean的预期方法是什么?我想保留DefaultUserDestinationResolver的大部分功能,只需修改它生成的主题的格式。

    由于没有其他答案,我想我会发布我们使用的解决方案。基本上,我们使用了一个
    @Primary
    bean,它覆盖了默认的解析器

    在下面的示例中,
    MyUserDestinationResolver
    是一个扩展了
    DefaultUserDestinationResolver
    的类,覆盖了
    getTargetDestination()
    方法。
    SimpUserRegistry
    对象是基类构造函数所必需的,但实际上我们的实现根本没有使用它

    @Configuration
    public class UserDestinationResolverFactory {
    
      @Inject
      SimpUserRegistry userRegistry;
    
      @Bean
      @Primary
      public UserDestinationResolver userDestinationResolver() {
        return new MyUserDestinationResolver(this.userRegistry);
      }
    }
    

    我想你没想到这一点吧?我也需要知道怎么做。你的问题给了我一个我没有的暗示(re,@Primary),但我正在努力让它起作用。有什么想法吗?如何替换DefaultUserDestinationResolver?(FWIW,如果使用集群RabbitMQ环境,它将无法非常有效地工作,因为生成的队列名称之间经常会发生冲突,从而产生可预见的灾难性结果。)@VanessaWilliams我将添加一个答案,说明我们是如何做到这一点的,而不是试图将代码挤入注释部分。