Java – MongoDb authentication using Hibernate OGM

MongoDb authentication using Hibernate OGM… here is a solution to the problem.

MongoDb authentication using Hibernate OGM

I can authenticate on my mongoDB using shell commands:

#mongo -u user -p pwd --authenticationDatabase admin
MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
> use admin
switched to db admin
> show users
{
        "_id" : "admin.ladmin",
        "user" : "ladmin",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "userAdminAnyDatabase",
                        "db" : "admin"
                }
        ]
}
{
        "_id" : "admin.living",
        "user" : "user",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "lvdb"
                }
        ]
}

I was also able to authenticate it with the java driver :

List<ServerAddress> seeds = new ArrayList<ServerAddress>();
seeds.add(new ServerAddress(this.configurationResources.getMongodbServer(), this.configurationResources.getMongodbPort()));

List<MongoCredential> credentials = new ArrayList<MongoCredential>();
credentials.add(
    MongoCredential.createScramSha1Credential(
        this.configurationResources.getMongodbUsername(),
        this.configurationResources.getMongodbAuthenticationDatabase(),
        this.configurationResources.getMongodbPassword().toCharArray()
    )
);

this.mongoClient = new MongoClient(seeds, credentials);

Currently, I’m working on a project where I want to use Hibernate OGM. I set persistence.xml file:

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="mongo" transaction-type="JTA">
        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>

<class>com.living.persistence.entities.User</class>

<properties>
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
            <property name="hibernate.ogm.datastore.provider" value="org.hibernate.ogm.datastore.mongodb.impl.MongoDBDatastoreProvider"/>
            <property name="hibernate.ogm.datastore.database" value="lvdb"/>
            <property name="hibernate.ogm.datastore.host" value="mongo"/>
            <property name="hibernate.ogm.datastore.port" value="27017"/>
            <property name="hibernate.ogm.datastore.username" value="user"/>
            <property name="hibernate.ogm.datastore.password" value="pwd"/>
            <property name="hibernate.ogm.mongodb.authentication_mechanism" value="SCRAM_SHA_1"/>

<property name="hibernate.ogm.mongodb.connection_timeout" value="5000"></property>
            <property name="hibernate.ogm.datastore.document.association_storage" value="IN_ENTITY"></property>
            <property name="hibernate.ogm.mongodb.association_document_storage" value="GLOBAL_COLLECTION"></property>
            <property name="hibernate.ogm.mongodb.write_concern" value="MAJORITY"></property>
            <property name="hibernate.ogm.mongodb.read_preference" value="PRIMARY_PREFERRED"></property>
        </properties>
    </persistence-unit>
</persistence>

As you can see, I’m using SCRAM-SHA1 as the authentication mechanism.

Still, I get this message when I try to deploy my application:

Caused by: org.hibernate.service.spi.ServiceException: OGM000071: Unable to start datatore provider
Caused by: org.hibernate.HibernateException: OGM001214: Unable to connect to MongoDB instance: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=mongo:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName=’user’, source=’lvdb’, password=, mechanismProperties={}}}, caused by {com.mongodb.MongoCommandException: Command failed with error 18: ‘Authentication failed.’ on server mongo:27017. The full response is { \”ok\” : 0.0, \”errmsg\” : \”Authentication failed.\”, \”code\” : 18, \”codeName\” : \”AuthenticationFailed\” }}}]
Caused by: com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=mongo:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName=’user’, source=’lvdb’, password=, mechanismProperties={}}}, caused by {com.mongodb.MongoCommandException: Command failed with error 18: ‘Authentication failed.’ on server mongo:27017. The full response is { \”ok\” : 0.0, \”errmsg\” : \”Authentication failed.\”, \”code\” : 18, \”codeName\” : \”AuthenticationFailed\” }}}]”}}

Solution

Hibernate OGM is currently using the database name as the authentication database. This is a bug and I’m dealing with it.

In your example (by the way, everything seems to be correct), you want to connect to
“lvdb” db but you defined a user in the “admin” database. Hiebernate OGM is actually looking for users in the “lvdb” database.

Update: This issue is now fixed in the latest stable release (5.1.0.Final), you can select the name of the authentication database using the property hibernate.ogm.mongodb.authentication_database (admin is the default name).

Related Problems and Solutions