MongoDB程序新数据库身份验证失败

时间:2017-01-22 20:25:49

标签: mongodb spring-boot-gradle-plugin

我有一个使用MongoDB并启用了身份验证的远程租户数据库应用程序。在运行期间,我必须以编程方式创建新租户数据库,创建新租户数据库用户,创建新集合,并使用用户元数据写入新数据库。我的问题是我没有正确设置租户用户授权。我能够创建新的租户数据库和角色凭证“readWrite”的数据库用户。我也可以正确地将文档写入“users”集合。如果我使用我的管理员凭据,我可以访问租户数据库并检查用户文档没有问题。但是,如果我稍后尝试使用新创建的数据库用户凭据访问数据库,则会收到不正确的用户凭据异常。下面是我创建新租户数据库的代码,

 MongoCredential adminCredentials = MongoCredential
      .createCredential(adminuid, admindb, adminpw.toCharArray());
 ServerAddress adminSA = new ServerAddress(mongoConnectionUri, mongoPort);

 // Create the Mongo Password Vault Client & Document Template
 MongoClient adminclient = new MongoClient(adminSA, Arrays.asList(adminCredtials)):
 MongoClient adminclient MongoClient(adminSA,Arrays.asList(adminCredentials));
 DB tenant = adminclient.getDB(tenantdb);

 // Create pwvdb user
 DBObject pwvdbrole = new BasicDBObject();
 pwvdbrole.put("role", pwvrole);
 pwvdbrole.put("db", pwvdb);

 ArrayList<DBObject> pwvdbroles = new ArrayList<DBObject>();
 pwvdbroles.add(pwvdbrole);

 DBObject pwvaultcmd = new BasicDBObject();
 pwvaultcmd.put("createUser", pwvuid);
 pwvaultcmd.put("pwd", pwvpw);
 pwvaultcmd.put("roles", pwvdbroles);

 CommandResult result = tenant.command(pwvaultcmd);
 if (result.ok()) {
      System.out.println("Tenant Credentials: OK");
 } else {
      System.out.println("Tenant Credentials Error: " +
      result.getErrorMessage());
 }

 // Create users Collection
 DBCollection tenantCollection =
      tenant.getCollection(tenantcollection);

 // Create user default credentials & update user collection
 BasicDBObject userdocument = new BasicDBObject();
 userdocument.put("firstname", userfirstname);
 userdocument.put("lastname", userlastname);
 userdocument.put("email", useremail);
 userdocument.put("username", username);
 userdocument.put("password", pwencoder.encode(userpassword));
 userdocument.put("role", Integer.parseInt(userrole));

 // Create admin web portal users uid/pw
 tenantCollection.insert(userdocument);

 pwvclient.close();

因为客户端是远程的,所以我使用我的admin userid,pw和db作为凭据。但是,使用新租户数据库名称设置MongoDB租户客户端。这可能是我出错的地方,但我不知道如何使用我尚未创建的用户远程访问数据库。这些数据库是在运行时创建的,我不知道应用程序启动时租户用户的名称。

2 个答案:

答案 0 :(得分:0)

有两个不同的位置可以创建用户权限,这可能会造成混淆。两者都可以在代码中动态完成。

租户数据库中的用户角色

最简单的选项是您在租户数据库中创建所需的用户。您应该将runCommand callcreateUser command documented here的文档结构一起使用。您将在租户数据库中创建此用户。该角色应该是readWrite或其他任何记录。

稍后您将验证该同一个数据库的用户和密码。

您还可以在Admin DB中集中所有用户管理,每个createUser调用枚举所需的每个数据库/角色对的角色。如果您需要解释,请告诉我。它的工作方式与在那里创建用户的方式基本相同,也可以对该DB进行身份验证。然后切换到要在同一MongoClient上访问的数据库。

我无法发布2个其他有用的链接,因为如果我不是一个足够活跃的海报(10个声誉),发布超过2个链接的奇怪限制。

答案 1 :(得分:0)

这是我为了让它发挥作用所做的。我想指出的两个关键事项是admino和testops MongoDB模板。请注意,在adminops中,我使用了MongoDB管理员凭据,但指向了testdb。在testops中,我使用了新的testdb凭据并指向了testdb。我的错误是adminops。我使用了不正确的admindb。获得roleobj和cmd也有点棘手,但我还是想出来了。

package com.belcan;

import java.util.ArrayList;
import java.util.Arrays;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;

import com.mongodb.BasicDBObject;
import com.mongodb.CommandResult;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;

@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
public class PreConfigTestApplication implements CommandLineRunner {

    public static void main(String[] args) {

        // Fire off Spring Boot & Embedded Linux
        SpringApplication.run(PreConfigTestApplication.class, args);
    }

    @Override
    public void run(String...args) throws Exception {

        String testdb = "testdb";
        String testuid = "skm";
        String testpw = "password";

        // Set up credentials
        MongoCredential admincredentials = MongoCredential
                .createCredential(adminuid, admindb, adminpw.toCharArray());
        ServerAddress adminsa = new ServerAddress(mongoConnectionUri, mongoPort);


        // Create the Mongo Client & Document Template
        MongoClient adminclient = new MongoClient(adminsa,Arrays.asList(admincredentials));
        MongoOperations adminops = new MongoTemplate(adminclient, testdb);

        // First create new user
        DBObject roleobj = new BasicDBObject();
        roleobj.put("role", "readWrite");
        roleobj.put("db", "testdb");

        ArrayList<DBObject> array = new ArrayList<DBObject>();
        array.add(roleobj);

        DBObject cmd = new BasicDBObject();
        cmd.put("createUser", testuid);
        cmd.put("pwd", testpw);
        cmd.put("roles", array);

        // Create new User
        CommandResult result = (CommandResult) adminops.executeCommand(cmd);

        // check to see if command is ok
        if (result.ok()) {
            System.out.println("createUser Command: OK");
        } else {
            System.out.println("createUser Error:" + result.getErrorMessage());
        }

        // switch to testdb
        MongoOperations testops = new MongoTemplate(adminclient, testdb);

        // Create the user object
        User user = new User();
        user.setFirstname("mickey");
        user.setLastname("mouse");
        user.setEmail("mmouse@gmail.com");
        user.setUsername("mmouse");
        user.setPassword("mmouse1");
        user.setRole("USER");
        user.setStatus("ACTIVE");

        // Now save it
        testops.save(user, "users");

        // Close Database Connection
        adminclient.close();


        //
        // Now see if we can open the file with the new uid/pw
        //

        // Set up credentials
        MongoCredential testcredentials = MongoCredential
                .createCredential(testuid, testdb, testpw.toCharArray());
        ServerAddress testsa = new ServerAddress(mongoConnectionUri, mongoPort);


        // Create the Mongo Client & Document Template
        MongoClient testclient = new MongoClient(testsa,Arrays.asList(testcredentials));
        MongoOperations myops = new MongoTemplate(testclient, testdb);

        User myuser = new User();
        myuser.setFirstname("Daffy");
        myuser.setLastname("Duck");
        myuser.setEmail("dduck@gmail.com");
        myuser.setUsername("dduck");
        myuser.setPassword("dduck1");
        myuser.setRole("USER");
        myuser.setStatus("ACTIVE");

        // Now save it
        myops.save(myuser,"users");

        // Lets print it out
        System.out.println("Print Results");
        ArrayList<User> userout = (ArrayList<User>) myops.findAll(User.class, "users");
        for (int i = 0; i < userout.size(); i++) {

            System.out.println(userout.get(i));

        }

        System.out.println("\n\nAll Done....");

        // Close the database
        testclient.close();

    }

        // MongoDB Connection URI
        @Value("${spring.data.mongodb.uri}") 
        private String mongoConnectionUri;

        // MongoDB Connection Port
        @Value("${spring.data.mongodb.port}")
        private int mongoPort;

        // MongoDB userid
        @Value("${mongo.server.admin.db}")
        private String admindb;

        // MongoDB admin password
        @Value("${mongo.server.admin.pw}")
        private String adminpw;

        // MongoDB admin userid
        @Value("${mongo.server.admin.uid}")
        private String adminuid;



}