我有一个使用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租户客户端。这可能是我出错的地方,但我不知道如何使用我尚未创建的用户远程访问数据库。这些数据库是在运行时创建的,我不知道应用程序启动时租户用户的名称。
答案 0 :(得分:0)
有两个不同的位置可以创建用户权限,这可能会造成混淆。两者都可以在代码中动态完成。
最简单的选项是您在租户数据库中创建所需的用户。您应该将runCommand call与createUser 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;
}