non-loopback access denied error while configuring Spring websocket with rabbitmq

Viewed 2479

I am building a Spring Websocket application that user RabbitMQ as message broker.

The configuration file is provided below

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableStompBrokerRelay("/topic")
            .setRelayHost("192.168.1.8")
            .setRelayPort(61613)
            .setClientLogin("user")
            .setClientPasscode("user");

    //config.enableSimpleBroker("/topic");
    config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").withSockJS();   
}
}

But when I am running the application it gives me the following error

Received ERROR {message=[Bad CONNECT], content-type=[text/plain], version=[1.0,1.1,1.2], 
content-length=[26]} session=_system_ text/plain payload=non-loopback access denied

I have tried to give the required permissions in rabbitmq

sudo rabbitmqctl set_permissions -p / user ".*" ".*" ".*"

But still the problem appears. But the application works fine if I replace the ipaddress in 'setRelayHost(..)' with either 'localhost' or '127.0.0.1'.

2 Answers

I had this problem and after 2 hours of searching I could solved it. First of all I should bring some codes from StompBrokerRelayMessageHandler here:

@Override
protected void startInternal() {
    if (this.tcpClient == null) {
        StompDecoder decoder = new StompDecoder();
        decoder.setHeaderInitializer(getHeaderInitializer());
        Reactor2StompCodec codec = new Reactor2StompCodec(new StompEncoder(), decoder);
        this.tcpClient = new StompTcpClientFactory().create(this.relayHost, this.relayPort, codec);
    }

    if (logger.isInfoEnabled()) {
        logger.info("Connecting \"system\" session to " + this.relayHost + ":" + this.relayPort);
    }

    StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECT);
    accessor.setAcceptVersion("1.1,1.2");
    accessor.setLogin(this.systemLogin);
    accessor.setPasscode(this.systemPasscode);
    accessor.setHeartbeat(this.systemHeartbeatSendInterval, this.systemHeartbeatReceiveInterval);
    accessor.setHost(getVirtualHost());
    accessor.setSessionId(SYSTEM_SESSION_ID);
    if (logger.isDebugEnabled()) {
        logger.debug("Forwarding " + accessor.getShortLogMessage(EMPTY_PAYLOAD));
    }

    SystemStompConnectionHandler handler = new SystemStompConnectionHandler(accessor);
    this.connectionHandlers.put(handler.getSessionId(), handler);

    this.stats.incrementConnectCount();
    this.tcpClient.connect(handler, new FixedIntervalReconnectStrategy(5000));
}

So as you see in these lines :

accessor.setLogin(this.systemLogin);
accessor.setPasscode(this.systemPasscode);

it uses systemLogin and systemPasscode to login into rabbitmq server. The default values for these parameters is "guest" which is defined at the top of the class:

private String systemLogin = "guest";

private String systemPasscode = "guest";

With "guest" user you can just login to system in localhost.

So you should set these parameters in the configuration:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableStompBrokerRelay("/topic")
            .setRelayHost("192.168.1.8")
            .setRelayPort(61613)
            .setClientLogin("user")
            .setClientPasscode("user")
            .setSystemLogin("user")
            .setSystemPasscode("user");

    //config.enableSimpleBroker("/topic");
    config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").withSockJS();   
}
}

After this configuration if you run this command:

sudo rabbitmqctl set_permissions -p / user ".*" ".*" ".*"

every thing goes well.

Related