MongoDB 程序新数据库验证失败

MongoDB Program New Database Authentication Fails

我有一个远程租户数据库应用程序使用 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();

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

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

租户数据库中的用户角色

最简单的选择是在租户数据库中创建您想要的用户。你应该使用runCommand call with the document structure for the createUser command documented here。您将在租户数据库中创建此用户。该角色应该是 readWrite 或任何其他已记录的角色。

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

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

我无法 post 2 个其他有用的链接,因为如果我不够活跃,post 超过 2 个链接的奇怪限制 poster(10 声望)。

以下是我为让它工作所做的工作。我想指出的两个关键点是 adminops 和 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;



}