我在公司环境中使用spring-messaging websockets。 spring-messaging组件在DMZ中运行。它通过防火墙连接到ActiveMQ代理网络到内部网络。使用spring-security在DMZ中对连接进行身份验证,并且可以使用用户主体。
我需要订阅特定于用户的主题,内部网络中的服务可以通过它们与ActiveMQ的连接来发布。弹出消息/user
前缀似乎提供了此功能。
开箱即用,如果我通过身份验证并订阅/user/foo/bar
主题,那么DefaultUserDestinationResolver
会将此转换为会话ID,而在ActiveMQ中,我会看到由STOMP连接器订阅的订阅到/foo/bar-userjf44st89
的主题。在我的场景中有两个问题。
无法将会话标识jf44st89
转换回用户标识,因此内部网络中的服务无法通过其ActiveMQ连接发布到特定用户。它们不是,也绝不会是从内部网络通过防火墙发送到原始消息传递组件运行的DMZ的允许路由,因此任何涉及发布到spring-messaging组件的解决方案都是
似乎没有任何东西可以阻止经过身份验证但未经授权的用户尝试猜测会话ID并订阅/foo/bar-userjf44st89
等主题。不太可能成功,但我不太可能不可能。
所以我想用我自己的bean来增强DefaultUserDestinationResolver
,它会创建/user/user-id/session-id/foo/bar
形式的订阅,它可以解决这两个问题,并允许内部服务使用ActiveMQ *
通配符忽略session-id路径组件。
我的主要问题是如何最好地取代DefaultUserDestinationResolver
?它由AbstractMessageBrokerConfiguration
类创建为bean。用户是否打算创建自己的@Primary
UserDestinationResolver bean?我想保留DefaultUserDestinationResolver
的大部分功能,只需修改它生成的主题的格式。
答案 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);
}
}