Andy Brown
Andy Brown

Reputation: 13009

how to customize spring-messaging websockets user subscriptions?

I'm using spring-messaging websockets in a corporate environment. The spring-messaging component runs in the DMZ. It is connected to an ActiveMQ broker network through a firewall into the internal network. Connections are authenticated in the DMZ using spring-security and the user principal is made available.

I need to make subscriptions to user-specific topics that services in the internal network can publish to through their connectivity to ActiveMQ. The spring-messaging /user prefix appears to offer this facility.

Out of the box, if I am authenticated and I make a subscription to a topic of /user/foo/bar then DefaultUserDestinationResolver transforms this into a session id and in ActiveMQ I see a subscription made by the STOMP connector to a topic of /foo/bar-userjf44st89. There are two problems with this in my scenario.

  1. The session-id jf44st89 cannot be transformed back to a user id so a service in the internal network cannot publish to a specific user through its ActiveMQ connection. Their is not, and never will be, a permitted route originating from the internal network through the firewall to the DMZ where the spring-messaging component runs so any solution involving publishing to the spring-messaging component is out.

  2. There appears to be nothing to stop an authenticated but unauthorised user from trying to guess the session id and make subscriptions to topics such as /foo/bar-userjf44st89. Unlikely to succeed, but I prefer impossible to unlikely.

So I'd like to enhance DefaultUserDestinationResolver with my own bean that will create subscriptions of the form /user/user-id/session-id/foo/bar which should solve both the issues and allow internal services to use the ActiveMQ * wildcard to ignore the session-id path component.

My main question is how to best replace DefaultUserDestinationResolver? It is created as a bean by the AbstractMessageBrokerConfiguration class. Is the intended approach for users to create their own @Primary UserDestinationResolver bean? I'd like to retain most of the functionality of DefaultUserDestinationResolver and just modify the format of the topic that it generates.

Upvotes: 3

Views: 660

Answers (1)

Andy Brown
Andy Brown

Reputation: 13009

Since no other answer was suggested I thought I'd post the solution that we went with. Basically we went with an @Primary bean that overrides that replaces the default resolver.

In the below example MyUserDestinationResolver is a class that extends DefaultUserDestinationResolver, overriding the getTargetDestination() method. The SimpUserRegistry object is required by the base class constructor but is not actually used by our implementation at all.

@Configuration
public class UserDestinationResolverFactory {

  @Inject
  SimpUserRegistry userRegistry;

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

Upvotes: 0

Related Questions