2

I'm using mongodb community version 4.2.13 and go driver version 1.5.

My go application is running on the same host as db, but getting the following error when trying to make a connection:

connection() error occured during connection handshake: auth error:
sasl conversation error: unable to authenticate using mechanism
"SCRAM-SHA-256": (AuthenticationFailed) Authentication failed.

Here is how I created the admin account:

use admin
db.createUser({
  user: "admin1",
  pwd: "passwd12#$",
  roles: ["root"],
  mechanisms: ["SCRAM-SHA-256"]
})

db.system.users.update(
  { _id: "admin.admin1", "db": "admin" },
  {
    $addToSet: {
      authenticationRestrictions: { clientSource: ["127.0.0.1"] }
    }
  }
)

Go app code snippet

package main

import (
    "context"
    "fmt"
    "time"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    uri := fmt.Sprintf(
        "mongodb://%s:%s@%s:%d/admin?authSource=admin&authMechanism=SCRAM-SHA-256",
        "admin1",
        "passwd12#$",
        "127.0.0.1",
        27017,
    )
 
    // Prints "mongodb://admin1:passwd12#$@127.0.0.1:27017/admin?authSource=admin&authMechanism=SCRAM-SHA-256"
    fmt.Println(uri)
    ctx, cancel := context.WithTimeout(context.Background(), 10 * time.Second)
    defer cancel()
    client, err := mongo.Connect(
        ctx,
        options.Client().ApplyURI(uri),
    )
    if err != nil {
        panic(err)
    }
    defer func() {
        err = client.Disconnect(ctx)
        if err != nil {
            panic(err)
        }
    }()
    err = client.Ping(ctx, nil)
    if err != nil {
        panic(err)
    }
    fmt.Println("pinged")
}

I tried the following, but all of them didn't work:

  • Encoding username and password using url.QueryEscape
  • Trying "localhost" instead of "127.0.0.1"
  • Removing "authMechanism=SCRAM-SHA-256" in uri

As a side note, connecting to the Mongo shell with the exact same uri, and that worked.

call-me-corgi
  • 193
  • 4
  • 10
  • 1
    I am not familiar with go, perhaps you have to escape the $ dollar sign in your password. – Wernfried Domscheit Mar 20 '21 at 10:17
  • 1
    Did you try to remove the 'authenticationRestrictions'? I would assume you have to put your real IP address, not the loopback IP – Wernfried Domscheit Mar 20 '21 at 10:19
  • 1
    See the server log for the error. – D. SM Mar 20 '21 at 11:37
  • 1
    Note that the proper way to add an authentication restriction is to include it in the object passed to [createUser](https://docs.mongodb.com/manual/reference/method/db.createUser/#db-createuser) or [updateUser](https://docs.mongodb.com/manual/reference/method/db.updateUser/#db-updateuser). Not sure if those make a difference or not. – Joe Mar 21 '21 at 02:53
  • I figured it out. I looked at the log as @D. SM suggested, and it said 2021-03-21T15:22:25.768+0900 I ACCESS [conn102] Failed to acquire user 'admin1@admin' because of unmet authentication restrictions: Restriction '{anyOf: [{allOf: [{"clientSource": ["127.0.0.1/32"]}]}]}' in '{allOf: [{anyOf: [{allOf: [{"clientSource": ["127.0.0.1/32"]}]}]}]}' unmet" I guess the db thinks the go app's source ip is illegal cuz it's "127.0.0.1/32", not "127.0.0.1". Now I'm investigating 1) Why this happens only with the go driver 2) How can I make all IPs of the form "127.0.0.1/*" be accepted as well. – call-me-corgi Mar 21 '21 at 06:32

3 Answers3

1

Add ssl=false to your uri. Worked for me

hackfeed
  • 48
  • 5
1

You could try using 'options.Credential' to pass the authentication settings.

Seems like a cleaner way than formatting an URI that needs to be parsed later on.

https://docs.mongodb.com/drivers/go/current/fundamentals/auth/

clientOpts := options.Client().SetHosts(
    []string{"localhost:27017"},
).SetAuth(
    options.Credential{
        AuthSource: "<authenticationDb>",
        AuthMechanism: "SCRAM-SHA-256",
        Username: "<username>",
        Password: "<password>",
    }
)
client, err := mongo.Connect(context.TODO(), clientOpts)
superstes
  • 11
  • 2
1

Based on MongoDB documentation for the authentication process, there is a parameter to identify which database is used for authentication besides the target database on the URI.

While in mongoshell you can use this line

mongo "mongodb://Admin:${DBPASSWORD}@<host>:<port>/admin?authSource=admin"

I used that information to add ?authSource=admin to my CONNECTION_URL

CONNECTION_URL=mongodb://root:example@mongo:27017/my_database?retryWrites=true&w=majority&authSource=admin

That worked for me. Hope it does for you too.

For detailed information please review https://www.mongodb.com/features/mongodb-authentication

BlackStar
  • 78
  • 1
  • 1
  • 7