Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attempt to switch database target during SASL authentication

I try to setup a Mongo DB in Spring Boot project. I've set an uri in application.yml:

spring:
  data:
    mongodb:
      uri: mongodb://user:pass@localhost:27017/mydbname

But application fails to read data from repository with error:

Attempt to switch database target during SASL authentication.

Line where error occurs (kotlin):

val emails = emailRepository.findAllByStatus(READY_TO_SEND)

where

interface EmailRepository : MongoRepository<Email, String> {
    fun findAllByStatus(status: EmailStatus) : Collection<Email>
}

and

data class Email(
    @Id
    @get:JsonIgnore
    var id: String? = null,
    @get:NotNull
    val from: MailActor,
    @get:NotEmpty
    val to: Collection<MailActor>,
    @get:NotEmpty
    val subject: String,
    @get:NotEmpty
    val htmlText: String,
    val attachments: Collection<Attachment> = listOf(),
    val cc: Collection<MailActor> = listOf(),
    val bcc: Collection<MailActor> = listOf(),
    @get:JsonIgnore
    val status: EmailStatus = EmailStatus.READY_TO_SEND,
    @get:JsonIgnore
    val created: LocalDateTime = LocalDateTime.now(),
    @get:JsonIgnore
    val lastSendAttempt: LocalDateTime? = null,
)

The same error occurs with findAll and save operations on repository (and likely others too)

Stack trace:

Caused by: com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='user', source='user', password=<hidden>, mechanismProperties=<hidden>}
    at com.mongodb.internal.connection.SaslAuthenticator.wrapException(SaslAuthenticator.java:235) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:80) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:51) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.SaslAuthenticator.doAsSubject(SaslAuthenticator.java:241) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:51) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.InternalStreamConnectionInitializer.authenticate(InternalStreamConnectionInitializer.java:168) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:63) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:144) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.UsageTrackingInternalConnection.open(UsageTrackingInternalConnection.java:51) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.open(DefaultConnectionPool.java:431) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:115) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:100) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.DefaultServer.getConnection(DefaultServer.java:92) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:119) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.client.internal.ClientSessionBinding$SessionBindingConnectionSource.getConnection(ClientSessionBinding.java:135) ~[mongodb-driver-sync-4.1.1.jar:na]
    at com.mongodb.internal.operation.FindOperation$1.call(FindOperation.java:653) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.operation.FindOperation$1.call(FindOperation.java:650) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:582) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:650) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:78) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:178) ~[mongodb-driver-sync-4.1.1.jar:na]
    at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:135) ~[mongodb-driver-sync-4.1.1.jar:na]
    at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:92) ~[mongodb-driver-sync-4.1.1.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2790) ~[spring-data-mongodb-3.1.2.jar:3.1.2]
    ... 33 common frames omitted
Caused by: com.mongodb.MongoCommandException: Command failed with error 17 (ProtocolError): 'Attempt to switch database target during SASL authentication.' on server localhost:27017. The full response is {"ok": 0.0, "errmsg": "Attempt to switch database target during SASL authentication.", "code": 17, "codeName": "ProtocolError"}
    at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:175) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:359) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:280) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:33) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.SaslAuthenticator.sendSaslContinue(SaslAuthenticator.java:195) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.SaslAuthenticator.access$200(SaslAuthenticator.java:43) ~[mongodb-driver-core-4.1.1.jar:na]
    at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:69) ~[mongodb-driver-core-4.1.1.jar:na]
    ... 55 common frames omitted

I am able to connect to mongo via Intellij Idea client with the same credentials.

I run mongo db with docker-compose

version: '3.1'

services:
  mongodb:
    image: mongo
    container_name: my-service-mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: user
      MONGO_INITDB_ROOT_PASSWORD: pass
      MONGO_INITDB_DATABASE: mydbname
    ports:
      - 27017:27017
    volumes:
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro

where mongo-init.js is

db.createUser(
    {
        user: "user",
        pwd: "pass",
        roles: [
            {
                role: "readWrite",
                db: "mydbname"
            }
        ]
    }
);

What is going on? The only place in the internet where I found this error message is... mongo source code 8].

Any help appreciated.

like image 537
14 revs, 3 users 99% Avatar asked Jan 08 '21 13:01

14 revs, 3 users 99%


2 Answers

spring:
  data:
    mongodb:
      uri: mongodb://admin:[email protected]:27017/dbname?authSource=admin

add authSource param

like image 99
ChanningQiu Avatar answered Oct 01 '22 03:10

ChanningQiu


If you:

  • Have multiple similar accounts (with same credentials), one in "admin" and the other in another database.
  • Intend to log in with the other account not in the "admin" database.
  • Have SASL enabled.

Then you may be affected by JAVA-4290, which is caused by speculative authentication only supporting the "admin" database, in mongodb-driver-core versions before 4.3.2. This resulted in the client successfully authenticating with the wrong account (the one in the admin database) via speculative authentication, only for MongoDB to trap the error when the SASL Continue message is sent. It does so with a Protocol Error, as you have observed.

As of Spring Boot 2.5.4, the version of mongodb-driver-core that ships with Spring Boot is only 4.2.3.

like image 21
SP193 Avatar answered Oct 01 '22 01:10

SP193