[DOCS-3370] Clarify that even though in 2.6 all users are *stored* in the admin db, they are still scoped to individual dbs same as ever Created: 08/May/14  Updated: 31/May/14  Resolved: 31/May/14

Status: Closed
Project: Documentation
Component/s: manual
Affects Version/s: None
Fix Version/s: v1.3.6

Type: Task Priority: Major - P3
Reporter: Spencer Brody (Inactive) Assignee: Kay Kim (Inactive)
Resolution: Done Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to SERVER-3301 Allow admin user to login to any data... Closed
Participants:
Days since reply: 9 years, 37 weeks, 4 days ago

 Description   

this page says: "MongoDB stores all user information, including credentials and authorization information, for a MongoDB instance in the system.users collection in the admin database."

There are several other places on that page that reference user information being stored in the admin db, but doesn't make clear that that is just about storage. It's more or less an implementation detail. Users still have home databases like they always did, and you still have to send authentication commands to the right database.



 Comments   
Comment by Githook User [ 31/May/14 ]

Author:

{u'username': u'kay-kim', u'name': u'kay', u'email': u'kay.kim@10gen.com'}

Message: DOCS-3370 authentication client user and clarifications
Branch: master
https://github.com/mongodb/docs/commit/a452b50a6cadeeb8ea341b15b223564701c377dc

Comment by Kay Kim (Inactive) [ 29/May/14 ]

Hi Hendy –
yes to the your second statement but no to the first statement.

  • You create the user in the database you want to associate with the user.
  • In 2.6, MongoDB uses a centralized model for storing user information by storing all user information (including the user's name, password, and the database) in the admin database.

The following is a query on the admin database's system.users collection. As you can see for my user reportsUser, the database db associated with the user is reporting.

> use admin
switched to db admin
> db.system.users.find()
  { 
    "_id" : "reporting.reportsUser", 
    "user" : "reportsUser",
    "db" : "reporting", 
    "credentials" : { "MONGODB-CR" : "b3ef921dd60d4810081234af83cd688b" },
     "roles" : [ { "role" : "read", "db" : "reporting" }, { "role" : "read", "db" : "products" }, { "role" : "read", "db" : "sales" } ]
  }

So in summary, create the user in the database you want to associate the user; in my example reporting database for the reportsUser. Then, to authenticate, you authenticate the user against that same database; in my example, authenticate reportsUser agains the reporting database.

Hope this helps. Let me know if you have any further questions.

Comment by Hendy Irawan [ 29/May/14 ]

kay.kim@10gen.com Wait... your example stores users in the reporting database (see the title of this JIRA ticket), not the admin database.

or you're actually saying that MongoDB internally stores users from the reporting database inside the admin database?

Comment by Kay Kim (Inactive) [ 28/May/14 ]

Hi Hendy –
sorry for the confusion. We'll clarify the documentation soon. But to address your immediate concern, in 2.6, you can still create a user in the target DB using the API provided. MongoDB will store the user information, including the target DB for the user in the admin database for you, but as a developer, that should be transparent since that's just an implementation detail of MongoDB. From a developer's perspective, you've created a user that exists in the target DB.

For example, I created a reportsUser in the reporting database.

>     use reporting
switched to db reporting
>     db.createUser(
         {
           user: "reportsUser",
           pwd: "12345678",
           roles: [ 
              { role: "read", db: "reporting" },
              { role: "read", db: "products" },
              { role: "read", db: "sales" }
           ]
         }
     )
Successfully added user: {
	"user" : "reportsUser",
	"roles" : [
		{
			"role" : "read",
			"db" : "reporting"
		},
		{
			"role" : "read",
			"db" : "products"
		},
		{
			"role" : "read",
			"db" : "sales"
		}
	]
}
 

Then to log in, I authenticate to the reporting database

$ mongo -u reportsUser -p 12345678 --authenticationDatabase reporting

This logs me in as the reportsUser who can only perform the read operations on the 3 databases:

MongoDB shell version: 2.6.1
connecting to: test
Error while trying to show server startup warnings: not authorized on admin to execute command { getLog: "startupWarnings" }
> use reporting
switched to db reporting
> db.foo.find()
> use admin
switched to db admin
> db.foo.find()
error: { "$err" : "not authorized for query on admin.foo", "code" : 13 }
> use test
switched to db test
> db.foo.find()
error: { "$err" : "not authorized for query on test.foo", "code" : 13 }
> use products
switched to db products
> db.foo.find()
> quit()
 

Hope this helps.

Regards,

Kay

Comment by Hendy Irawan [ 28/May/14 ]

> how authentication works from the perspective of a driver author or an end user should be the same in 2.6 as in 2.4, although the way you create and update user definitions is different.

I don't think this is completely true, or I misunderstood it.

2.4 create user: create user in target DB -> OK
2.4 auth: login to target DB as user in that DB -> OK
2.4 shell: mongo -uuser target -> OK

2.6 create user: create user in admin DB, using roles to target DB -> OK
2.6 auth: login to target DB as user in that DB -> not authenticated
2.6 auth: login to target DB as user in admin DB, then authenticate to target DB -> OK
2.6 shell: mongo -uuser target -> not authenticated
2.6 shell: mongo -uuser --authenticationDatabase admin target -> OK

Conclusion is:
1. if developer want to use the 2.6 way of storing users in admin DB, then he has to change how he logs in to MongoDB whether via driver or shell
2. if developer want to keep using the 2.4 way of storing users in each DB, then the way he logs in to MongoDB remains unchanged. However in case of Java API, the DB.authenticate() method is deprecated now, which is confusing. How can it is deprecated when it's still the only way to do this and there's not an alternative?

Comment by Spencer Brody (Inactive) [ 27/May/14 ]

I can't speak to the deprecation of the java driver method, perhaps jeff.yemin knows more?
But the behavior of how authentication works from the perspective of a driver author or an end user should be the same in 2.6 as in 2.4, although the way you create and update user definitions is different.

Comment by Hendy Irawan [ 20/May/14 ]

"you still have to send authentication commands to the right database."

This seems conflicting with MongoDB Java API's deprecation notice, which authenticates the client, not per database:

@deprecated Please use

{@link MongoClient#MongoClient(java.util.List, java.util.List)} to create a client, which will authenticate all connections to server

From DB.java :

/**
* Authenticates to db with the given credentials. If this method (or {@code authenticate}) has already been
* called with the same credentials and the authentication test succeeded, this method will return true. If this method
* has already been called with different credentials and the authentication test succeeded,
* this method will throw an {@code IllegalStateException}. If this method has already been called with any credentials
* and the authentication test failed, this method will re-try the authentication test with the
* given credentials.
*
* @param username name of user for this database
* @param password password of user for this database
* @return the CommandResult from authenticate command
* @throws MongoException if authentication failed due to invalid user/pass, or other exceptions like I/O
* @throws IllegalStateException if authentication test has already succeeded with different credentials
* @dochub authenticate
* @see #authenticate(String, char[])
* @deprecated Please use {@link MongoClient#MongoClient(java.util.List, java.util.List)}

to create a client, which will authenticate all connections to server
*/
@Deprecated
public synchronized CommandResult authenticateCommand(String username, char[] password)

Generated at Thu Feb 08 07:45:34 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.