• MongoDB基础之 用户和数据库基于角色的访问控制


    mongod 关键字参数:--auth 

    默认值是不需要验证,即 --noauth,该参数启用用户访问权限控制;当mongod 使用该参数启动时,MongoDB会验证客户端连接的账户和密码,以确定其是否有访问的权限。如果认证不通过,那么客户端不能访问MongoDB的数据库。

    这个参数我们可以写在配置文件中,表示每次启动服务都打开auth认证,在这里我们是加在了mongod的启动指令中,如下所示

    [root@:vg_adn_tidbCkhsTest /usr/local/mongodb]#bin/mongo -u "admin" -p "123456" --authenticationDatabase "admin"
    MongoDB shell version v3.4.18
    connecting to: mongodb://127.0.0.1:27017
    MongoDB server version: 3.4.18
    > db
    test

    这里的“admin”数据库是我们在安装mongo的时候就已经创建的,并且在数据库中创建了admin用户,且拥有“userAdminAnyDatabase”角色

    下面讲解基于角色的访问控制

    角色是授予User在指定资源上执行指定操作的权限,MongoDB官方手册对角色的定义是:

    A role grants privileges to perform the specified actions on resource.

    MongoDB为了方便管理员管理权限,在DB级别上预先定义了内置角色;如果用户需要对权限进行更为细致的管理,MongoDB允许用户创建自定义的角色,能够在集合级别上控制User能够执行的操作。
    MongoDB使用角色(Role)授予User访问资源的权限,Role决定User能够访问的数据库资源和执行的操作。一个User能够被授予一个或多个Role,如果User没有被授予Role,那么就没有访问MongoDB系统的权限。

    A user is granted one or more roles that determine the user’s access to database resources and operations. Outside of role assignments, the user has no access to the system.

    1,内置角色(Built-In Roles)

    内置角色是MongoDB预定义的角色,操作的资源是在DB级别上。MongoDB拥有一个SuperUser的角色:root,拥有最大权限,能够在系统的所有资源上执行任意操作。

    数据库用户角色(Database User Roles):

    • read:授予User只读数据的权限
    • readWrite:授予User读写数据的权限

    数据库管理角色(Database Administration Roles):

    • dbAdmin:在当前dB中执行管理操作
    • dbOwner:在当前DB中执行任意操作
    • userAdmin:在当前DB中管理User

    备份和还原角色(Backup and Restoration Roles):

    • backup
    • restore

    跨库角色(All-Database Roles):

      • readAnyDatabase:授予在所有数据库上读取数据的权限
      • readWriteAnyDatabase:授予在所有数据库上读写数据的权限
      • userAdminAnyDatabase:授予在所有数据库上管理User的权限
      • dbAdminAnyDatabase:授予管理所有数据库的权限

    现在我们举例子介绍一下

    上面我们已经创建好了admin用户,该用户拥有有grant权限,我们创建的admin用户是在admin数据库中创建的。即:账号管理的授权权限。注意一点,帐号是跟着库走的,所以在指定库里授权,必须也在指定库里验证(auth)。

    由于我们的admin用户建立了 userAdminAnyDatabase 角色,用来管理用户,可以通过这个角色来创建、删除用户。验证:需要开启auth参数

    [root@:vg_adn_tidbCkhsTest:23.22.172.65:172.31.22.29 /usr/local/mongodb]#bin/mongo -u "admin" -p "123456" --authenticationDatabase "admin"
    MongoDB shell version v3.4.18
    connecting to: mongodb://127.0.0.1:27017
    MongoDB server version: 3.4.18
    > db
    test
    > use admin
    switched to db admin
    > db
    admin
    > show users;
    {
        "_id" : "admin.admin",
        "user" : "admin",
        "db" : "admin",
        "roles" : [
            {
                "role" : "dbOwner",
                "db" : "test"
            },
            {
                "role" : "userAdminAnyDatabase",
                "db" : "admin"
            }
        ]
    }
    > show dbs;
    admin  0.000GB
    local  0.000GB
    test   0.000GB
    test1  0.000GB

    我们连接上去admin用户之后,在admin数据库中就有了权限,注意admin用户拥有的角色是userAdminAnyDatabase。所以才可以创建用户等等操作

    > use test2                                   #在test2库中创建账号
    switched to db test2
    > db.createUser(
    ... {
    ... user:"test",
    ... pwd:"test",
    ... roles:[{role:"readWrite",db:"test2"}]
    ... }
    ... )
    Successfully added user: {
        "user" : "test",
        "roles" : [
            {
                "role" : "readWrite",
                "db" : "test2"
            }
        ]
    }
    > show users;
    {
        "_id" : "test2.test",
        "user" : "test",
        "db" : "test2",
        "roles" : [
            {
                "role" : "readWrite",
                "db" : "test2"
            }
        ]
    }

    现在我们开始验证一下:

    > use test2
    switched to db test2> db
    test2
    > db.abc.insert({"name":"chaofeng","id":1})
    WriteResult({
        "writeError" : {
            "code" : 13,
            "errmsg" : "not authorized on test2 to execute command { insert: "abc", documents: [ { _id: ObjectId('5bea73410816d4c446c6c0d1'), name: "chaofeng", id: 1.0 } ], ordered: true }"
        }
    })

    因为我目前还是admin登录的,所以在test2数据库中,admin用户没有权限,只有我们刚刚建立的“test”用户才有权限。

    注意:admin用户只是拥有了创建用户,删除用户的角色,这并不是最高权限。

    所以现在我想在test2数据库下插入数据,我得使用test用户才行。

    这里还要注意一点:

    1、我在admin数据库中认证test用户

    > db.auth("test","test")
    Error: Authentication failed.
    0
    > db
    admin

    我在admin数据库中使用test用户认,来让test用户可以访问test2数据库,是失败的。记住一点:在admin下创建的账户,不能直接在admin库上验证。

    2、我在test2数据库中认证test用户

    > db.auth("test","test")
    1
    > db
    test2

    这样就成功了,记住一点:在哪个库上创建的账户,就在那里认证,也说明了一点,数据库账户是跟着数据库走的,先有数据库,然后才有账户去认证这个数据库,从而有权限操作。

    现在我们的test用户已经可以登录到test2数据库中操作了,我们尝试一下

    > use test2
    switched to db test2> db.abc.insert({"name":"chaofeng","id":1})
    WriteResult({ "nInserted" : 1 })
    > db.abc.find()
    { "_id" : ObjectId("5bea76f00816d4c446c6c0d2"), "name" : "chaofeng", "id" : 1 }
    > 

    最后我们再看一下数据库中创建的所有账户

    > use admin
    switched to db admin> db.system.users.find().pretty()
    {
        "_id" : "admin.admin",
        "user" : "admin",
        "db" : "admin",
        "credentials" : {
            "SCRAM-SHA-1" : {
                "iterationCount" : 10000,
                "salt" : "2VmpmkRbVjolDoXjzbjHTw==",
                "storedKey" : "/Rd7OGTHEsGhsK8ZsFGe8DOzHTk=",
                "serverKey" : "8+JA2FBdUVtvo3AZNNDSvREZpOg="
            }
        },
        "roles" : [
            {
                "role" : "dbOwner",
                "db" : "test"
            },
            {
                "role" : "userAdminAnyDatabase",
                "db" : "admin"
            }
        ]
    }
    {
        "_id" : "test1.ccf",
        "user" : "ccf",
        "db" : "test1",
        "credentials" : {
            "SCRAM-SHA-1" : {
                "iterationCount" : 10000,
                "salt" : "cqPSk8h1ucAnJEl3mjx8MQ==",
                "storedKey" : "kNNTRqVv63fVy0r1KH9Oem0iKNo=",
                "serverKey" : "yTO6i7IIu7wuTEfd+VJG/l59veM="
            }
        },
        "roles" : [
            {
                "role" : "readWrite",
                "db" : "test1"
            }
        ]
    }
    {
        "_id" : "test2.test",
        "user" : "test",
        "db" : "test2",
        "credentials" : {
            "SCRAM-SHA-1" : {
                "iterationCount" : 10000,
                "salt" : "0K+o35PrySZbdTq0kl79vg==",
                "storedKey" : "z3Z8dDswfQsnJ98qpUG8qChIafQ=",
                "serverKey" : "b6kLZoYhZwgxXmSNLpVIqyr6AyE="
            }
        },
        "roles" : [
            {
                "role" : "readWrite",
                "db" : "test2"
            }
        ]
    }

    查看所有的用户我们必须在admin数据库下,在其他的数据中是查看不到的。比如

    > use test2
    switched to db test2
    > db.system.users.find().pretty()

    同样的查看数据库用户的指令,在test2数据库中就不起作用,什么也查不出来。

    同样的道理,当我们登录到mongo的时候,想要进入到admin库中查看所有用户的操作也是需要验证的,比如:

    [root@:vg_adn_tidbCkhsTest /usr/local/mongodb]#bin/mongo
    MongoDB shell version v3.4.18
    connecting to: mongodb://127.0.0.1:27017
    MongoDB server version: 3.4.18
    > db
    test
    > use test2
    switched to db test2
    > use admin
    switched to db admin
    > db.system.users.find().pretty()
    Error: error: {
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { find: "system.users", filter: {} }",
        "code" : 13,
        "codeName" : "Unauthorized"
    }
    > 

    紧接着这里我们还没有在test2库中认证账户密码,还能访问数据库吗?

    > use test2
    switched to db test2
    > show dbs                                                                              #发现连数据库都查看不了
    2018-11-13T07:09:19.437+0000 E QUERY    [thread1] Error: listDatabases failed:{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
        "code" : 13,
        "codeName" : "Unauthorized"
    } :
    _getErrorWithCode@src/mongo/shell/utils.js:25:13
    Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
    shellHelper.show@src/mongo/shell/utils.js:814:19
    shellHelper@src/mongo/shell/utils.js:704:15
    @(shellhelp2):1:1
    > db.abc.find()                                          #test2数据库的记录也查看不了
    Error: error: {
        "ok" : 0,
        "errmsg" : "not authorized on test2 to execute command { find: "abc", filter: {} }",
        "code" : 13,
        "codeName" : "Unauthorized"
    }
    > db.auth("test","test");                                    #开启认证账户
    1
    > db.abc.find()                                          #成功
    { "_id" : ObjectId("5bea76f00816d4c446c6c0d2"), "name" : "chaofeng", "id" : 1 }
    > 

    总结:mongo数据库和别的数据库认证过程是不一样的,我们无需退出客户端便可以自动切换用户,来实现对不同数据库的操作。mongo中,在哪个数据库下创建的用户,就在哪个数据库下开启认证,也就是说,在A数据库创建的用户user1,只能在数据库A下面开启认证,在B数据库下面认证user1是不能成功的,在B数据库下只能认证user2数据库。数据库账户是跟着数据库走的。

    现在我想删除数据库,

    > use test2
    switched to db test2
    > show dbs
    admin  0.000GB
    local  0.000GB
    test1  0.000GB
    test2  0.000GB
    > db.auth("test","test");
    1
    > db.abc.find()
    { "_id" : ObjectId("5bea76f00816d4c446c6c0d2"), "name" : "chaofeng", "id" : 1 }
    { "_id" : ObjectId("5bea7b4f6aeeebc0eb076f44"), "name" : "chen", "id" : 2 }
    > db.dropDatabase();
    {
        "ok" : 0,
        "errmsg" : "not authorized on test2 to execute command { dropDatabase: 1.0 }",
        "code" : 13,
        "codeName" : "Unauthorized"
    }

    发现是不能删除数据库的,仔细一想就知道test用户只有对当前test2数据库读写操作,但是没有删除权限。

    我们再对test2数据库创建一个用户,使其拥有管理权限

    > db
    test2
    > db.createUser(
    ... {
    ... user:"gl",
    ... pwd:"gl",
    ... roles:[{role:"dbOwner",db:"test2"}]
    ... }
    ... )
    Successfully added user: {
        "user" : "gl",
        "roles" : [
            {
                "role" : "dbOwner",
                "db" : "test2"
            }
        ]
    }> db.auth("gl","gl")
    1
    > db.dropDatabase()
    { "dropped" : "test2", "ok" : 1 }

    现在我们创建的gl用户拥有dbOwner角色,也就是对当前数据库拥有最高管理权限,这个时候就可以删除数据库test2了。

  • 相关阅读:
    LeetCode485 最大连续1的个数
    LeetCode167 两数之和 II
    js浮点数类型
    js整数类型
    js布尔类型
    js重复赋值 js数据交换 js调式方法
    JavaScript变量
    数据类型分类
    重复赋值 数据交换 查看程序执行结果
    JS注释 JS变量
  • 原文地址:https://www.cnblogs.com/FengGeBlog/p/9952387.html
Copyright © 2020-2023  润新知