如何自定义spring-messaging websockets用户订阅?

时间:2016-03-30 08:07:48

标签: java spring spring-security spring-websocket spring-messaging

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

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

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

  1. 无法将会话标识jf44st89转换回用户标识,因此内部网络中的服务无法通过其ActiveMQ连接发布到特定用户。它们不是,也绝不会是从内部网络通过防火墙发送到原始消息传递组件运行的DMZ的允许路由,因此任何涉及发布到spring-messaging组件的解决方案都是

  2. 似乎没有任何东西可以阻止经过身份验证但未经授权的用户尝试猜测会话ID并订阅/foo/bar-userjf44st89等主题。不太可能成功,但我不太可能不可能。

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

    我的主要问题是如何最好地取代DefaultUserDestinationResolver?它由AbstractMessageBrokerConfiguration类创建为bean。用户是否打算创建自己的@Primary UserDestinationResolver bean?我想保留DefaultUserDestinationResolver的大部分功能,只需修改它生成的主题的格式。

1 个答案:

答案 0 :(得分:0)

由于没有提出其他答案,我以为我会发布我们采用的解决方案。基本上我们使用覆盖的@Primary bean取代了默认的解析器。

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

@Configuration
public class UserDestinationResolverFactory {

  @Inject
  SimpUserRegistry userRegistry;

  @Bean
  @Primary
  public UserDestinationResolver userDestinationResolver() {
    return new MyUserDestinationResolver(this.userRegistry);
  }
}