3

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

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

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

  1. session-idjf44st89无法转换回用户 id,因此内部网络中的服务无法通过其 ActiveMQ 连接发布给特定用户。它们不是,也永远不会是从内部网络通过防火墙到运行 spring-messaging 组件的 DMZ 的允许路由因此任何涉及发布到 spring-messaging 组件的解决方案都已失效。

  2. 似乎没有什么可以阻止经过身份验证但未经授权的用户尝试猜测会话 ID 并订阅诸如/foo/bar-userjf44st89. 不太可能成功,但我更喜欢不可能。

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

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

4

1 回答 1

0

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

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

@Configuration
public class UserDestinationResolverFactory {

  @Inject
  SimpUserRegistry userRegistry;

  @Bean
  @Primary
  public UserDestinationResolver userDestinationResolver() {
    return new MyUserDestinationResolver(this.userRegistry);
  }
}
于 2017-07-14T07:57:33.590 回答