Search code examples
javaspring-bootrabbitmqspring-amqpspring-rabbit

Spring amqp - no compatible authentication mechanism found - server offered []


I'm trying to connect spring boot app to rabbit mq through EXTERNAL auth mechanism (https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl).

I get following error:

org.springframework.amqp.AmqpIOException: java.io.IOException: No compatible authentication mechanism found - server offered []
    at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:70) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:594) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:687) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:257) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2225) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2198) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2178) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueInfo(RabbitAdmin.java:459) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueProperties(RabbitAdmin.java:443) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.attemptDeclarations(AbstractMessageListenerContainer.java:1891) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.redeclareElementsIfNecessary(AbstractMessageListenerContainer.java:1858) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1384) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1230) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.io.IOException: No compatible authentication mechanism found - server offered []
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:343) ~[amqp-client-5.17.0.jar:5.17.0]
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1225) ~[amqp-client-5.17.0.jar:5.17.0]
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1173) ~[amqp-client-5.17.0.jar:5.17.0]
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.connectAddresses(AbstractConnectionFactory.java:632) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.connect(AbstractConnectionFactory.java:607) ~[spring-rabbit-3.0.5.jar:3.0.5]
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:557) ~[spring-rabbit-3.0.5.jar:3.0.5]
    ... 12 common frames omitted

Dependency:

<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-amqp</artifactId>
                <version>3.2.1</version>
            </dependency>

RabbitMq version: rabbitmq:3.12.1-management

rabbitmq.conf contains those properties:

default_user=guest
default_pass=guest
listeners.tcp=none
listeners.ssl.default=5672
ssl_options.cacertfile=/etc/rabbitmq/cert/ca_bundle.pem
ssl_options.certfile=/etc/rabbitmq/cert/certificate.pem
ssl_options.keyfile=/etc/rabbitmq/cert/key.pem
ssl_options.password=pass
ssl_options.verify=verify_peer
ssl_options.fail_if_no_peer_cert=true
ssl_options.versions.1=tlsv1.2
ssl_options.depth=1
auth_mechanisms.1=EXTERNAL
ssl_cert_login_from=common_name

application.properties:

spring.rabbitmq.ssl.enabled=true
spring.rabbitmq.ssl.algorithm=TLSv1.2
spring.rabbitmq.ssl.key-store=keystore.p12
spring.rabbitmq.ssl.key-store-password=pass
spring.rabbitmq.ssl.key-store-type=PKCS12
spring.rabbitmq.ssl.trust-store=truststore.p12
spring.rabbitmq.ssl.trust-store-password=pass
spring.rabbitmq.ssl.trust-store-type=PKCS12

I declared following method to include sasl config:

  @Bean
  public AmqpTemplate amqpTemplate(ConnectionFactory connectionFactory) {
    CachingConnectionFactory cachingConnectionFactory = (CachingConnectionFactory) connectionFactory;
    cachingConnectionFactory.getRabbitConnectionFactory().setAutomaticRecoveryEnabled(true);
    cachingConnectionFactory.getRabbitConnectionFactory().setSaslConfig(DefaultSaslConfig.EXTERNAL);
    cachingConnectionFactory.resetConnection();

    RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
    rabbitTemplate.setMessageConverter(converter());
    return rabbitTemplate;
  }

Solution

  • I'm not sure what is listeners.ssl.default=5672 on the RabbitMQ configuration side, but sounds like you override a default SSL port to that one.

    The logic in Spring Boot is like this:

    return (Optional.ofNullable(getSsl().getEnabled()).orElse(false)) ? DEFAULT_PORT_SECURE : DEFAULT_PORT;
    

    Where:

    private static final int DEFAULT_PORT_SECURE = 5671;
    

    So, probably need to look into providing that port explicitly:

    spring.rabbitmq.port=5672
    

    You also might not need that custom RabbitTemplate bean and just add a ConnectionFactoryCustomizer to setup that DefaultSaslConfig.EXTERNAL into an auto-configured com.rabbitmq.client.ConnectionFactory.

    It is also not recommended to use setAutomaticRecoveryEnabled(true): https://docs.spring.io/spring-amqp/reference/amqp/connections.html#auto-recovery