Reputation: 13009
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.
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.
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
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