Restheart for MongoDB, ACL and users - mongodb

I have a MongoDB instance with the atlas sample databases and I'm trying to configure Restheart on it.
I have restheart configured with mongoRealmAuthenticator and MongoAclAuthorizer, with ACL and USERS collections in the restheart database, and the following mongo-mounts:
- what: /sample_weatherdata
where: /sample_weatherdata
The Users collection have the admin user and a user called sample_weatherdata with user role. The ACL collection have the following ACL.
{
"_id" : "userCanGetOwnCollection",
"roles" : [
"user"
],
"predicate" : "method(GET) and path-template('/{userid}') and equals(#user.userid, ${userid})",
"priority" : 100,
"_etag" : ObjectId("62322951a40a5c34cad71769")
}
But when I try to get the information from the sample_weatherdata db with curl (curl -k -u sample_weatherdata:secret -X GET https://xxxxx:4443/sample_weatherdata?page=1), I'm getting an error on the restheart logs:
21:01:22.702 [XNIO-1 task-1] DEBUG o.r.s.authorizers.FileAclAuthorizer - role user, permission (roles=[user],predicate=method(GET) and path-template('/{userid}') and equals(#user.userid, ${userid}) and qparams-contain(page) and qparams-blacklist(filter, sort)
), resolve false
21:01:22.716 [XNIO-1 task-1] DEBUG o.r.s.authorizers.MongoAclAuthorizer - role user, permission id BsonString{value='userCanGetOwnCollection'}, resolve false
21:01:22.718 [XNIO-1 task-1] INFO org.restheart.handlers.RequestLogger - GET https://xxxxxxx:4443/sample_weatherdata?page=1 from /10.100.200.100:55555 => status=403 elapsed=26ms contentLength=0 username=sample_weatherdata roles=[user]
Any idea if I'm missing something or how to configure the ACLs to allow the query?

If you use the default authenticator, i.e. mongoRealmAuthenticator the correct id property of the user is #user._id
So your permission should be:
{
"_id" : "userCanGetOwnCollection",
"roles" : [ "user" ],
"predicate" : "method(GET) and path-template('/{userid}') and equals(#user._id, ${userid})",
"priority" : 100
}
In the example acl.json you have:
NOTE: the id of the user is #user.userid with fileRealmAuthenticator and #user._id with mongoRealmAuthenticator
I'm the main committer of RESTHeart, and given that now mongoRealmAuthenticator is the default authenticator, I have just updated the example acl.json and related documentation to use #user._id

Related

MongoDB - How to Change current logged in user's password? [duplicate]

I used db.addUser(...) to create a user at some point in the past. How do I now change that user's password?
I logged in with a user with userAdmin role. What command do I use to change another user's password?
Edit 2
I need this answered for the v2.4 style addUser and privilege documents
http://docs.mongodb.org/manual/tutorial/add-user-to-database/
http://docs.mongodb.org/manual/reference/privilege-documents/
Edit
It has been suggested that I use the 2.2 addUser syntax to change the password. This does not work:
db.addUser({user: "test", pwd: "oldPassword", roles: ["readWrite"]})
db.addUser("test", "newPassword")
gives
uncaught exception: couldn't add user: system.users entry must not have both 'roles' and 'readOnly' fields
db.changeUserPassword("test", "newPassword")
https://groups.google.com/d/msg/mongodb-user/KkXbDCsCfOs/rk2_h-oSbAwJ
https://jira.mongodb.org/browse/DOCS-1515
Finally found it!
To change a password, just run the addUser command again.
db.addUser("coolguy", "newxH#x0rPasswd", true);
this might help.
Becareful about the argument passed. That is for readOnly option.
EDIT :
Steps I followed in : Added a new user
> db.addUser("admin","firstpwd")
{
"user" : "admin",
"readOnly" : false,
"pwd" : "40a84fcba954c8924d277f23b0f880b1",
"_id" : ObjectId("51966ec8c7ad876ba0319438")
}
exit
> db.auth("admin","firstpwd")
1
Changing the password
> db.addUser("admin","secondpwd")
{
"_id" : ObjectId("51966ec8c7ad876ba0319438"),
"user" : "admin",
"readOnly" : false,
"pwd" : "82f4e416844349418281a3eca1cf6082"
}
exit
db.auth("admin","secondpwd")
1
MongoDB shell version: 2.4.3

mongodb authorization exception in JMeter : code13

In MongoDB 3.2 I've setup a user with rights:
db.createUser(
{
user: "username",
pwd: "pass",
roles: [ { role: "readWrite", db: "dbname" }]
}
)
db.auth("username", "pass" )
When I use the JMeter(2.13) to connect to the database (using Jmeter's elements MongoDB Source Config , MongoDB Script) and run a query like this:
db.mycollectionname.find()
I get this error:
error: { "$err" : "not authorized on dbname to execute command { $eval: \"db.mycollectionname.find()\", args: [] }" , "code" : 13}
While I have provided all the necessary details Server Address List , Database , User , Password to Jmeter's MongoDB Source Config , MongoDB Script respectively.
Any ideas what can be happening?
I had the same issue. I had to set up a user with eval permissions even though this is not recommended (even the admin user does not have these permissions).
Try that and change you script to look at the new user and it should work.

Cannot access authenticated MongoDB collection from ReactiveMongo Play app

I have a MongoDB server where I have enabled authentication and created users with DB-specific permissions. The user for this app is defined as shown below i.e. geoAdmin has read, readWrite and dbOwner permissions for the relevant database:
MongoDB shell version: 3.0.0
connecting to: 192.168.2.89/test
> use geo_db
switched to db geo_db
> db.getUser("geoAdmin")
{
"_id" : "geo_db.geoAdmin",
"user" : "geoAdmin",
"db" : "geo_db",
"roles" : [
{
"role" : "read",
"db" : "geo_db"
},
{
"role" : "dbOwner",
"db" : "geo_db"
},
{
"role" : "readWrite",
"db" : "geo_db"
}
]
}
The following query works OK i.e. connecting to the remote server from my local mongo client:
mint:~ $ mongo 192.168.2.89:27017 -u geoAdmin -p secret --authenticationDatabase geo_db
MongoDB shell version: 3.0.0
connecting to: 192.168.2.89/test
> use geo_db
switched to db geo_db
> db.LAD_DEC_2013_GB_BFE.findOne({},{'properties.LAD13NM':1})
{
"_id" : ObjectId("54ffe2824f0787ec1293017f"),
"properties" : {
"LAD13NM" : "Hartlepool"
}
}
I then connect to the same remote host from a ReactiveMongo Play app on the same local client, with this URL in the app config file:
# ReactiveMongo
mongodb.uri = "mongodb://geoAdmin:secret#192.168.2.89:27017/geo_db"
But when my app tries to read from the same collection, I get a MongoDB "code = 13" error:
[DetailedDatabaseException: DatabaseException['not authorized for query on geo_db.LAD_DEC_2013_GB_BFE' (code = 13)]]
The app works fine if I connect to a local MongoDB which does not have authentication enabled.
Any ideas what might be going wrong here?
ReactiveMongo 0.11.7.play23 is supporting mongo 3.0 auth-protocols, but is still using the old as default.
With ReactiveMongo 0.11.7.play23 -plugin, you can make it authenticate with mongo 3.0, by adding "?authMode=scram-sha1" to the end of your mongodb.uri.
E.g.:
mongodb.uri = "mongodb://geoAdmin:secret#192.168.2.89:27017/geo_db?authMode=scram-sha1"
mongo 2.6 uses MONGODB-CR auth protocol and 3.0 uses MONGODB-SHA-1 by default
reactivemongo use MONGODB-CR auth protocol(not sure)
downgrade mongodb 3.0 auth mechanisms to MONGODB-CR
login mongo noauth
remove all user
update the version document for the authSchema.
ex.
db.getSiblingDB("admin").system.users.remove( {} )
db.getSiblingDB("admin").system.version.update(
{ _id: "authSchema" },
{ $set: { currentVersion: 3 } }
);
add authSource parameter to mongodb url
ex.
mongodb.uri = "mongodb://geoAdmin:secret#192.168.2.89:27017/geo_db?authSource=geo_db"

Create Read only user in Mongo DB Instance for a particular database

I have created a user "mongo01testro" in the mongo01test database.
use mongo01test
db.addUser( "mongo01testro", "pwd01", true );
db.system.users.find();
{ "_id" : ObjectId("53xyz"), "user" : "mongo01testro", "readOnly" : true, "pwd" : "b9eel61" }
When I logged in from another session as this newly created user,
I am able to insert documents into the collection which is strange.
I am looking to do the following:
Create 2 separate users one for read only and one for read write for
each database.
Create an admin user which have sysadmin/dba access to all the
databases in MongoDB instance used for Backup/Recovery or admin
purpose.
Please kindly help.
Regards,
Parag
You forgot --auth to enable
Create Users
// ensure that we have new db, no roles, no users
use products
db.dropDatabase()
// create admin user
use products
db.createUser({
"user": "prod-admin",
"pwd": "prod-admin",
"roles": [
{"role": "clusterAdmin", "db": "admin" },
{"role": "readAnyDatabase", "db": "admin" },
"readWrite"
]},
{ "w": "majority" , "wtimeout": 5000 }
)
// login via admin acont in order to create readonly user
// mongo --username=prod-admin --password=prod-admin products
db.createUser({
"user": "prod-r",
"pwd": "prod-r",
"roles": ["read"]
})
Enable auth:
sudo vim /etc/mongod.conf # edit file
# Turn on/off security. Off is currently the default
#noauth = true
auth = true
sudo service mongod restart # reload configuiration
Check write restriction:
# check if write operation for readonly user
$ mongo --username=prod-r --password=prod-r products
MongoDB shell version: 2.6.4
connecting to: products
> db.laptop.insert({"name": "HP"})
WriteResult({
"writeError" : {
"code" : 13,
"errmsg" : "not authorized on products to execute command { insert: \"laptop\", documents: [ { _id: ObjectId('53ecb7115f0bfc61d8b1113e'), name: \"HP\" } ], ordered: true }"
}
})
# check write operation for admin user
$ mongo --username=prod-admin --password=prod-admin products
MongoDB shell version: 2.6.4
connecting to: products
> db.laptop.insert({"name": "HP"})
WriteResult({ "nInserted" : 1 })
# check read operation for readonly user
$ mongo --username=prod-r --password=prod-r products
MongoDB shell version: 2.6.4
connecting to: products
> db.laptop.findOne()
{ "_id" : ObjectId("53ecb54798da304f99625d05"), "name" : "HP" }
MongoDB changed the way it handles users in versions >= 2.2 and 2.6 and if you are updating mongodb you will have to Upgrade User Authorization Data to 2.6 Format.
In versions < 2.2 (legacy) you use the db.addUser(username, password, readOnly) function as #Hüseyin BABAL suggested. If you are using version > 2.2 or 2.6 you have a lot more control over what you can do with roles and privileges.
So assuming you use mongo v > 2.6 you can create something like:
use admin
db.createUser({
user: "myUsername",
pwd: "mypwd",
roles: [{
role: "userAdminAnyDatabase",
db: "admin"
}]
})
db.addUser({
user: "username",
pwd: "password",
roles: [{
role: "readWrite",
db: "myDBName"
}]
})
You can use the Build in Roles or you can even create custom roles.
So as you can see you clearly have a lot more options when using v > 2.6 when it comes to authentication and role management.
if the Access control is enabled on the MongoDB deployment, Then you should login by authenticating to the relevant database with admin user (or user with userAdmin role) which you want to control the access. to do that
mongo <db_name> -u <user_name> -p <user_password>
ex: mongo mongo01test -u admin -p admin_paaswrod
then execute the following query to create a read only user for current connected database,
db.createUser({user:"user_name",pwd:"password",roles:[{role:"read", db:"db_name"}]});
ex:db.createUser({user:"user_rd",pwd:"password",roles:[{role:"read", db:"mongo01test"}]});
create a user with both readWrite access,
db.createUser({user:"user_name",pwd:"password",roles:[{role:"readWrite", db:"db_name"}]});
ex:db.createUser({user:"user_rw",pwd:"pass_rw",roles:[{role:"readWrite", db:"mongo01test"}]});
to create a user with admin privileges,
use admin;
db.createUser({user:"admin_user_name",pwd:"password", roles:[{role:"dbAdmin", db:"admin"},{role:"readWriteAnyDatabase", db:"admin"},{role:"backup", db:"admin"},{role:"restore", db:"admin"}]});
Here is my scneario;
// Create admin user
use admin
db.addUser('root', 'strong_password');
// Read only user
use dbforuser1
db.addUser('user1', 'user1_pass', true);
// Read / Write access
use dbforuser2
db.addUser('user2', 'user2_pass');
If you want to login to dbforuser1
use dbforuser1
db.auth('user1', 'user1_pass')

MongoDB with Authentication

I am trying to get MongoDB running on my localhost (Windows) with authentication.
To do so, I first have to add a user, right?
I did so by starting the daemon using this command:
C:\[…]\mongod.exe -f C:\[…]\mongo.config
mongo.config contains the following:
# Basic database configuration
dbpath = C:\[…]\db\
bind_ip = 127.0.0.1
port = 20571
# Security
noauth = true
# Administration & Monitoring
nohttpinterface = true
After that I connected via this command:
C:\[…]\mongo.exe --port 20571 127.0.0.1
There I added a user:
> use admin
switched to db admin
> db.addUser('test', 'test')
{ "n" : 0, "connectionId" : 1, "err" : null, "ok" : 1 }
{
"user" : "test",
"readOnly" : false,
"pwd" : "a6de521abefc2fed4f5876855a3484f5",
"_id" : ObjectId("50db155e157524b3d2195278")
}
To check if everything worked I did the following:
> db.system.users.find()
{ "_id" : ObjectId("50db155e157524b3d2195278"), "user" : "test", "readOnly" : false, "pwd" : "a6de521abefc2fed4f5876855a3484f5" }
Which seemed OK to me.
After that I changed "noauth = true" to "auth = true" in the mongo.config file and restarted the daemon.
Now I expected to be able to connect with user and password:
C:\[…]\mongo.exe --port 20571 -u test -p test 127.0.0.1
Which denied access to me with this message:
MongoDB shell version: 2.0.4
connecting to: 127.0.0.1:20571/127.0.0.1
Wed Dec 26 16:24:36 uncaught exception: error { "$err" : "bad or malformed command request?", "code" : 13530 }
exception: login failed
So here's my question: Why does the login fail?
I can still connect without providing user and password, but can't access any data because "unauthorized db:admin lock type:-1 client:127.0.0.1". Which is actually what I expected.
As Andrei Sfat told me in the comments on the question I made 2 major errors.
First, I thought I could pass the IP to the Client as a simple argument. But you have to use --host for that.
Instead, the parameter I thought was the IP address actually should be the db name.
So the correct command to connect to a Server is as follows:
C:\[…]\mongo.exe --port 20571 -u test -p test --host 127.0.0.1 admin
Second, users are per database. As I only added the user "test" to the db "admin", it only works there.
Obviously the auth = true configuration wasn't load successfully. Did you forget the -f paramter when you restart the mongod.exe?
C:\[…]\mongod.exe -f C:\[…]\mongo.config