MongoDB: User Management (Create Users and Grant Roles)
Table of Contents
1. User Management Overview
Users in MongoDB are enforced only when authorization is enabled in mongod.conf (security.authorization: enabled), as shown in the connect post. These are the main differences from Oracle:
| MongoDB | Oracle |
|---|
| User: Created inside a specific authentication database. Same username can exist in different databases. | User: Global to the database. Username must be unique. |
| User and data are separate: creating a user does not create a database or schema or collection. | User = schema: CREATE USER also creates a schema that can own tables. |
Roles: built-in roles (read, readWrite, dbAdmin, userAdmin, root) and custom roles. | Roles: predefined roles (CONNECT, RESOURCE, DBA) and custom roles. |
Privileges: actions (such as find, insert) on a resource (a database or collection), grouped into roles. | Privileges: System privileges (CREATE TABLE) and object privileges (SELECT ON emp), granted to users or roles. |
| Account lock, password expiry and profiles: not available with native authentication. | Account lock, password expiry and profiles: ALTER USER ... ACCOUNT LOCK and PROFILE. |
2. Create a User
In MongoDB, switch to the database where the user should be created, then run createUser. The roles can be given at the same time. In Oracle, the user is created first and the privileges are granted separately.
| MongoDB | Oracle |
|---|
// Admin user with full access //
use admin
db.createUser({
user: "admin",
pwd: passwordPrompt(),
roles: [ { role: "root", db: "admin" } ]
})
| -- DBA user
CREATE USER admin_user IDENTIFIED BY "StrongPassword#1";
GRANT DBA TO admin_user;
|
// Application user (read and write on myFirstDB). The user is created in myFirstDB.//
use myFirstDB
db.createUser({
user: "appuser",
pwd: passwordPrompt(),
roles: [ { role: "readWrite", db: "myFirstDB" } ]
})
| -- Application user
CREATE USER appuser IDENTIFIED BY "StrongPassword#1"
DEFAULT TABLESPACE users
QUOTA UNLIMITED ON users;
GRANT CREATE SESSION TO appuser;
-- Read and write on the tables
GRANT SELECT, INSERT, UPDATE, DELETE
ON myfirstdb.students TO appuser;
|
# Connect as the new user (run from OS shell, not mongosh).
# Use the database where the user
# was created as authenticationDatabase.
mongosh -u appuser -p \
--authenticationDatabase myFirstDB
| -- Connect as the new user (OS shell)
-- (the service name is an example)
sqlplus appuser@//localhost:1521/ORCLPDB1
|
3. Grant and Revoke Roles
A role in MongoDB is given as { role, db }, which means the role applies to that database. The built-in roles and their closest Oracle equivalents are:
| MongoDB | Oracle |
|---|
read (read all collections of a database) | SELECT privilege on tables |
readWrite (read and write all collections of a database) | SELECT, INSERT, UPDATE, DELETE on tables |
dbAdmin (indexes, statistics, collection management) | Owner of the schema, or privileges such as CREATE ANY INDEX |
userAdmin (create users and roles in a database) | CREATE USER, ALTER USER, CREATE ROLE, GRANT ANY ROLE |
clusterMonitor (read-only monitoring) | SELECT_CATALOG_ROLE |
root (full access) | DBA role |
| MongoDB | Oracle |
|---|
// Grant a role to an existing user
use myFirstDB
db.grantRolesToUser("appuser", [
{ role: "read", db: "reportsDB" }
])
| -- Grant a privilege to an existing user
-- (Oracle grants table by table, or use a role)
GRANT SELECT ON reports.sales TO appuser;
|
// Revoke a role from a user
use myFirstDB
db.revokeRolesFromUser("appuser", [
{ role: "read", db: "reportsDB" }
])
| -- Revoke a privilege from a user
REVOKE SELECT ON reports.sales FROM appuser;
|
4. Create a Custom Role
When the built-in roles give too much, create a custom role with only the privileges you need. A privilege is a resource (database and collection) plus a list of actions. The common actions are find (SELECT), insert (INSERT), update (UPDATE) and remove (DELETE).
| MongoDB | Oracle |
|---|
// Create a custom role
use myFirstDB
db.createRole({
role: "studentsReader",
privileges: [
{ resource: { db: "myFirstDB",
collection: "students" },
actions: [ "find" ] }
],
roles: []
})
| -- Create a custom role
CREATE ROLE students_reader;
GRANT SELECT ON myfirstdb.students
TO students_reader;
|
// Grant the role to a user
db.grantRolesToUser("appuser", [
"studentsReader"
])
| -- Grant the role to a user
GRANT students_reader TO appuser;
|
// View the privileges of a role
db.getRole("studentsReader",
{ showPrivileges: true })
| -- View the privileges of a role
SELECT privilege, owner, table_name
FROM role_tab_privs
WHERE role = 'STUDENTS_READER';
|
// Drop the role
db.dropRole("studentsReader")
| -- Drop the role
DROP ROLE students_reader;
|
5. Manage Users
These commands work on the users of the current database in MongoDB, so run use first.
| MongoDB | Oracle |
|---|
// Change the password
use myFirstDB
db.changeUserPassword("appuser",
passwordPrompt())
| -- Change the password
ALTER USER appuser
IDENTIFIED BY "NewPassword#1";
|
// List the users of the current database
show users
| -- List the users
SELECT username, account_status, created
FROM dba_users
WHERE oracle_maintained = 'N';
|
// List the users of all databases
// (needs a privileged user)
db.getSiblingDB("admin")
.system.users.find({}, { user: 1, db: 1 })
| -- List the users (same query,
-- Oracle users are not per database)
SELECT username FROM dba_users
WHERE oracle_maintained = 'N';
|
// Show a user and its roles
db.getUser("appuser")
| -- Show the roles of a user
SELECT granted_role
FROM dba_role_privs
WHERE grantee = 'APPUSER';
|
// Drop the user. Only the user is removed, the data stays.
db.dropUser("appuser")
| -- Drop the user
-- (add CASCADE to also drop the
-- objects the user owns)
DROP USER appuser;
|
6. Verify the Current User
In the connectionStatus output, authenticatedUsers shows who you are and authenticatedUserRoles shows the roles you have. With showPrivileges: true it also lists the privileges.
| MongoDB | Oracle |
|---|
// Just who am I? (short output)
db.runCommand({ connectionStatus: 1 })
// Who am I + every single privilege? (verbose)
db.runCommand({ connectionStatus: 1, showPrivileges: true })
| -- Current user
SELECT USER FROM dual;
-- Roles of the current session
SELECT role FROM session_roles;
|
Caution: Your use of any information or materials on this website is entirely at your own risk. It is provided for educational purposes only. It has been tested internally, however, we do not guarantee that it will work for you. Ensure that you run it in your test environment before using.
Thank you
Rajasekhar Amudala