选择数据库后进行身份验证 [英] Authenticate After Picking the Database

查看:89
本文介绍了选择数据库后进行身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的MongoDB服务器中有3个数据库.我正在使用pymongo用Python3做一些脚本.

I have 3 databases in my MongoDB server. I am using pymongo to do some scripting with Python3.

我想使用最新版本和做法.打开客户端并选择数据库后,不推荐使用pymongo.MongoClient.['mydatabase'].authenticate的API. https://api.mongodb.com/python/current/api/pymongo/database.html

I want to use the latest versions and practices. Once I open the client and pick the database, the API for pymongo.MongoClient.['mydatabase'].authenticate is deprecated. https://api.mongodb.com/python/current/api/pymongo/database.html

在选择数据库之前(在拨打客户端时),身份验证似乎并没有流向数据库.不仅用于pymongo,而且当我使用mongo shell时也是如此.所以我觉得这就是问题所在.

Authentication prior to picking the database (while dialing the client) doesn't seem to flow down toward the database. Not just for pymongo, but also when I use mongo shell. So I have a feeling this is the issue.

script.py

script.py

import pymongo
from pymongo import MongoClient
u = getUser()         # function which prompts for username
p = getPassword()     # getpass.getpass('Password')
uri = formatUri(u, p) # formats 'mongodb://%s:%s@%s'.format(user, password, host)

client = MongoClient(uri)
db = client['mydb']
col = db.mycollection
for doc in col.find():
    print(doc)

我收到未获得数据库授权的错误.我知道我的帐户可以在Shell中使用,但是我必须先拨打客户端,然后使用db,然后再进行auth.

I get the error that I am not authorized for the database. I know my account works in shell but I have to dial the client first then use the db and then auth.

这是一个mongo shell示例:

Here's a mongo shell example:

$ mongo
MongoDB shell version: v3.4.10
Connecting to: mongodb://127.0.0.1:port
MongoDB server version: v3.4.10
> use mydb
switched to mydb
> db.auth("user", "pass")
1

有什么主意我可以在选择数据库后进行身份验证,或者一旦使用数据库就可以记住我拨号时使用的上下文?

Any idea how I can either auth after picking the database or once I use the db it remembers the context I dialed with?

推荐答案

您似乎在这里缺少了一些概念,因此我基本上会作为指南"来回答您应该做的事情.因此,身份验证"实际上并不是您在连接之后"进行的操作,而是在实际尝试进行身份验证时需要在正确的位置查看".

You seem to be missing some concepts here so I'll basically answer as a "guide" to what you should be doing instead. So "authentication' is not really something you do "after" connection, but rather you need to be "looking in the right place" when you actually attempt to authenticate.

我们可以从本质上按照启用身份验证中概述的过程开始>来自核心文档,但由于您希望在自己的用户帐户和本地目录下运行此测试"而进行了专门更改.

We can start this by essentially following the process outlined in Enable Auth from the core documentation, but specifically altered because you want to be running this "test" under your own user account and local directory.

因此,首先要选择一个本地工作目录,并为该目录下的数据库存储文件创建路径.在基于* nix的系统上,您可以执行以下操作:

So first would would want to pick a local working directory and make a path for the database storage files underneath that. On *nix based systems you can do something like:

mkdir -p scratch/data/db
cd scratch

然后,我们要启动一个没有任何其他选项的单独的MongoDB实例.确保端口不与任何其他正在运行的实例冲突:

Then we want to startup a separate MongoDB instance without any other options. Making sure the port does not conflict with any other running instance:

mongod --port 37017 --dbpath data/db

然后在新的终端或命令行窗口中,您可以连接到外壳程序:

In a new terminal or command line window, you can then connect to the shell:

mongo --port 37017

您始终希望至少一个具有管理特权的帐户至少创建帐户"并在遇到麻烦时进行更改,因此,请创建一个:

You always want at least one account with administrative privileges to at least "create accounts" and alter them in case you get in trouble, so create one:

use admin
db.createUser(
  {
    user: "admin",
    pwd: "admin",
    roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
  }
)

现在退出外壳程序并关闭在另一个终端或命令提示符下运行的现有mongod实例,然后使用--auth重新启动它:

Now exit the shell and close the existing mongod instance running in the other terminal or command prompt and then start it again using --auth:

mongod --auth --port 37017 --dbpath data/db

特定用户-确保您遵循这些规则

现在,您实际上要创建一个将由您的应用程序使用"的用户.因此,这些步骤对于确保正确无误至关重要.

Specific User - Make sure you follow these

Now you actually want to create a user that will be "used by your application". So these steps are important to ensure you get it right.

使用您的管理用户"登录外壳程序:

Log into a shell using your "adminstrative user":

mongo -u admin -p admin --port 37017 --authenticationDatabase 'admin'

您也可以按问题所示执行db.auth()方法,但是请注意,必须在"admin"名称空间上对此进行授权.

You can alternately do the db.auth() method as shown in the question, but as noted this must be authorised on the "admin" namespace.

接下来要做的是创建一个具有readWrite角色的用户,该用户可以访问"mydb"作为命名空间.对于踢,我们还将让该用户拥有readAnyDatabase,如果他们实际上无法使用它们执行任何其他操作,则允许他们列出"所有数据库名称空间.

The next thing you want to do is create a user with access to "mydb" as a namespace with the readWrite role. For kicks, we are also going to let this user have the readAnyDatabase allowing them to "list" all databases namespaces, if not actually being able to do anything else with them.

重要:您可以在"admin"名称空间中创建所有用户.这在将来的版本中将非常重要:

IMPORTANT: You create ALL your users in the "admin" namespace. And this will be very important in future releases:

use admin
db.createUser(
  {
    "user": "myuser",
    "pwd": "password",
    "roles": [
      { "role": "readWrite", "db": "mydb" },
      "readAnyDatabase"
    ]
  }
)

仅需其他输出,让我们看一下当前创建的用户:

Just for additional output, let's look at the current created users:

db.getUsers()
[
        {
                "_id" : "admin.admin",
                "user" : "admin",
                "db" : "admin",
                "roles" : [
                        {
                                "role" : "userAdminAnyDatabase",
                                "db" : "admin"
                        }
                ]
        },
        {
                "_id" : "admin.myuser",
                "user" : "myuser",
                "db" : "admin",
                "roles" : [
                        {
                                "role" : "readWrite",
                                "db" : "mydb"
                        },
                        {
                                "role" : "readAnyDatabase",
                                "db" : "admin"
                        }
                ]
        }
]

查看这些名称在命名方面的扩展方式,尤其是分配给每个用户的各个"db"键的值.这应该使您对MongoDB的查找方式及其原因有更多的了解.

See how these have expanded in naming, and particularly the values assigned to the various "db" keys on each user. This should give you a little more insight into how MongoDB looks this up and why.

最后,我们只想从python连接.因此,假设您已经安装了python和pymongo,那么它只是一个简单的清单即可进行验证:

Finally we just want to connect from python. So presuming you have python and pymongo installed already, then it's just a simple listing to verify:

import pymongo
from pymongo import MongoClient
client = MongoClient('mongodb://myuser:password@localhost:37017');

db = client['mydb']
col = db.test

col.remove()

col.insert_one({ "a": 1 })

for doc in col.find():
  print(doc)

显示已创建和列出的文档没有问题:

Which shows the document created and listed without problem:

{u'a': 1, u'_id': ObjectId('5a08e5e0760108251722a737')}

请注意,我们实际上不需要在这里提及"admin",因为这是驱动程序期望帐户是"的默认值,而您真正应该"这样做的位置.

Note that we don't actually need to make any mention of "admin" here, because this is the default where the driver "expects the accounts to be" and where you really "should" be doing it.

因此,假设您最初很困惑,而是在"mydb"下创建了用户:

So let's say you originally got all confused and created the user under "mydb" instead:

use mydb
db.createUser({ "user": "bert", "pwd": "password", "roles": ["readWrite"] })

如果您进入"admin",则该用户不在那里.但是,如果您查看"mydb":

If you go look in "admin" that user is not there. But if you look on "mydb":

use mydb
db.getUsers()
[
        {
                "_id" : "mydb.bert",
                "user" : "bert",
                "db" : "mydb",
                "roles" : [
                        {
                                "role" : "readWrite",
                                "db" : "mydb"
                        }
                ]
        }
]

因此,您可以看到实际的用户数据现在保存在哪里以及如何记录.

So you can see where the actual user data is now kept and how it has been recorded.

这里的简单情况是,您必须"告诉MongoDB从何处获得该用户的身份验证:

The simple case here is you "must" tell MongoDB where to obtain the authentication from for this user:

client = MongoClient('mongodb://bert:password@localhost:37017/mydb');

了解如何在连接字符串上添加"mydb".就是这样.

See how we add "mydb" on to the connection string. This is how it's done.

实际上,这是进行中"的过程,与所有驱动程序都将在建立连接方式,进行身份验证以及选择数据库的位置上保持一致.但是有一些基本规则:

This is actually "in progress" to be made consistent with ALL drivers in how connections are made and where authentication happens as well as where you select the database. But there are basic rules:

  1. 如果没有其他数据库名称空间提供身份验证凭据的连接详细信息,则将"admin"用作默认.

在连接字符串上提供数据库名称空间的地方,这将用于身份验证,这是数据库在连接字符串上的名称空间的实际意图.

Where there is a database namespace provided on the connection string, this will be used for authentication and this is the actual intent of the database namespace on the connection string.

尽管其他"驱动程序在连接字符串上的数据库名称空间的作用目前有所不同,但用法已更改为与所有使用"数据库名称空间实际上是API调用的驱动程序一致,而不是从连接字符串中分配.

Though other drivers "presently" differ in the role of the database namespace on the connection string, the usage is being changed to be consistent with all drivers that "using" a database namespace is in fact an API call, rather than being assigned from the connection string.

因此,需要进行身份验证的位置取决于在何处创建用户".但是您应该真正注意到"admin"是您应该"执行此操作的地方,而不是其他任何地方.

So where you need to authenticate depends on "where you created the user". But you should really be noting that "admin" is the place where you "should" be doing this instead of anywhere else.

连接后拒绝身份验证

尽管所有驱动程序实际上都具有与"admin"命名空间中:

Deprecation of Authenticate after connect

Whilst all drivers actually do have a similar method to authenticate(), which is used much like the shell example in the question, this method is now considered DEPRECATED as is mentioned throughout the content of the answer it is "intended" that you actually store your users in the "admin" namespace:

版本3.5中的更改:不建议使用.对多个用户进行身份验证与MongoDB 3.6中对逻辑会话的支持发生冲突.要作为多个用户进行身份验证,请创建MongoClient的多个实例."

这就是为什么此处的全部答案基于的原因,因为您打算创建新的连接实例,或者使用MongoDB 3.6中可用的会话"功能代替.

This is why the whole answer here is based on NOT using that method as you are meant to creating new connection instances, or using the "sessions" functionality available from MongoDB 3.6 instead.

这篇关于选择数据库后进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆