MongoDB权限管理代码分析

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: 本文主要介绍Mongodb RBAC(role based access control)权限管理机制,其核心是给每个用户赋予一定的权限,用户连接mongodb前需先验证,验证通过后即拥有用户的权限,权限决定了用户在某一组资源(如某个DB、某个特定集合)上可以执行哪些操作(比如增删改查、建索引)。.

本文主要介绍Mongodb RBAC(role based access control)权限管理机制,其核心是给每个用户赋予一定的权限,用户连接mongodb前需先验证,验证通过后即拥有用户的权限,权限决定了用户在某一组资源(如某个DB、某个特定集合)上可以执行哪些操作(比如增删改查、建索引)。

ActionType

db/auth/action_types.txt文件里包含mongo所有的action

ActionType代表一种操作,每个ActionType有一个唯一的ID,Role支持的所有操作通过ActionSet来描述,ActionSet实际是一个位图,支持某种操作时,其ID对应的bit置1.

ActionType相关的代码是由一个python脚本动态生成的

generate_action_types.py action_types.txt header_file source_file

ResourcePattern

ResourcePattern代表资源(某个数据库、某个集合等)匹配方式,由资源名称(DB.collection格式,如果为空代表匹配任意资源)及匹配方式组成

class {
private:
  MatchType _matchType;
  NamespaceString _ns;  
};

enum MatchType {
    matchNever = 0,              /// Matches no resource.
    matchClusterResource = 1,    /// Matches if the resource is the cluster resource.
    matchDatabaseName = 2,       /// Matches if the resource's database name is _ns.db().
    matchCollectionName = 3,     /// Matches if the resource's collection name is _ns.coll().
    matchExactNamespace = 4,     /// Matches if the resource's namespace name is _ns.
    matchAnyNormalResource = 5,  /// Matches all databases and non-system collections.
    matchAnyResource = 6         /// Matches absolutely anything.
};

Privilege

权限(Privilege)由ResourcePattern及支持的ActionSet构成,代表可以在匹配ResourcePattern的资源上可以执行ActionSet里的所有操作。

class Privilege {
private:
  ResourcePattern _resource;
  ActionSet _actions;
};

Role & PrivilegeVector

权限集合代表是一组权限的并集

typedef std::vector PrivilegeVector;

往PrivilegeVector里添加Previlege时,先检查ResourcePattern是否已经存在,如果已经存在,直接添加对应的ActionSet;如果不存在,则构造一个新的Previlege添加到Vector里。

void Privilege::addPrivilegeToPrivilegeVector(PrivilegeVector* privileges,
                                          const Privilege& privilegeToAdd) {
    for (PrivilegeVector::iterator it = privileges->begin(); it !=  privileges->end(); ++it) {
        if (it->getResourcePattern() == privilegeToAdd.getResourcePattern()) {
            it->addActions(privilegeToAdd.getActions());
            return;
        }
   }
   // No privilege exists yet for this resource
   privileges->push_back(privilegeToAdd);
}

Role

Role代表『对某些资源(Resource)可以执行哪些操作(action)』,每个Role包含一个PrivilegeVector,指定其拥有的权限。

BuiltIn Role

为方便管理,Mongodb已经内置了一组预先定义好的Role,比如read、readWrite等,auth模块里已经实现好了构造对应权限的接口

void addReadOnlyDbPrivileges(PrivilegeVector* privileges, StringData dbName);
void addReadWriteDbPrivileges(PrivilegeVector* privileges, StringData dbName);

每个Role跟一个DB(多个DB)关联,代表这个Role能操作的资源(Resource),由RoleName唯一标识。

class RoleName {
public:
    RoleName(StringData role, StringData dbname);
private:
    std::string _fullName;  // The full name, stored as a string.  "role@db".
    size_t _splitPoint;     // The index of the "@" separating the role and db name parts.      
};

User

每个User跟一个DB关联,由UserName唯一标识,多个DB下可能具有相同名字的User。每个User包含一组P

Class UserName {
public:
  UserName(StringData user, StringData dbname);
private:
  std::string _fullName;  // The full name, stored as a string.  "user@db".
  size_t _splitPoint;     // The index of the "@" separating the user and db name parts.
};

class User {
private:
  UserName _name;
  // Maps resource name to privilege on that resource
  ResourcePrivilegeMap _privileges;

  // Roles the user has privileges from
  unordered_set _roles;

  // Roles that the user indirectly has privileges from, due to role inheritance.
  std::vector _indirectRoles;
};

createUser

数据库命令createUser用于创建新用户,用户创建时需指定用户名、密码及分配的权限信息(ActionSet@ResourcePattern),用户的信息会存储在admin.system.users集合里。

mongodb用户也可直接通过insert、update、remove等直接操作admin.system.users集合,但强烈不建议这么做,所有的用户操作建议都通过createUser、updateUser、dropUser等数据库命令来完成。

auth

auth命令负责对连接进行认证,以确定该连接可以针对哪些资源执行什么操作,同一个DB可以被auth多次,以最终auth的用户权限为准。

class CmdAuthenticate : public Command {
public:
bool run(OperationContext* txn,
         const std::string& dbname,
         BSONObj& cmdObj,
         int options,
         std::string& errmsg,
         BSONObjBuilder& result);
}; 

每个连接对应一个AuthorizationSession,存储着连接上已通过验证的用户信息

class AuthorizationSession {
private:
    // All Users who have been authenticated on this connection.
UserSet _authenticatedUsers;
    // The roles of the authenticated users. This vector is generated when the authenticated
   // users set is changed.
std::vector _authenticatedRoleNames;

};

当mongod接受到用户请求时,会根据请求对应的操作需要的权限,在_authenticatedUsers进行匹配,如果包含所需权限,则该操作可以继续执行。

请求权限验证

用户建立连接后,就可以开始发送请求,针对集合的增删改查请求,主要包括OP_INSERT、OP_UPDATE、OP_DELETE等,这些请求在AuthorizationSession对应检查权限的方法。

Status checkAuthForUpdate(const NamespaceString& ns,
                          const BSONObj& query,
                          const BSONObj& update,
                          bool upsert);
Status checkAuthForInsert(const NamespaceString& ns, const BSONObj& document);
Status checkAuthForDelete(const NamespaceString& ns, const BSONObj& query);
...

还有一类请求是数据库命令,比如createUser、listCollections、listDatabases等,这些都是数据库命令,mongodb里每个命令都继承自Command类,需实现run、checkAuthForCommand等方法,其中checkAuthForCommand用于检查命令是否有权限执行;实际上就是检查命令操作的DB(或集合)及对应的操作类型是否在用户的PrivilegeVector里。Command的权限检查通过后就会执行run函数,完成命令的主体执行逻辑。

class Command {

    virtual Status checkAuthForCommand(ClientBasic* client, 
                                const std::string& dbname,
                                const BSONObj& cmdObj);
    virtual bool run(OperationContext* txn,
                 const std::string& db,
                 BSONObj& cmdObj,
                 int options,
                 std::string& errmsg,
                 BSONObjBuilder& result) = 0;
};
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
8月前
|
NoSQL 安全 MongoDB
Mongo DB之用户与权限管理、备份与恢复管理以及客户端工具的使用
MongoDB是一款灵活且高性能的文档型数据库,具有可扩展性和强大的查询功能,适用于各种应用场景。
653 1
|
10月前
|
NoSQL MongoDB 数据库
二.MongoDB入门-Mongodb权限管理
MongoDB入门-Mongodb权限管理
|
存储 NoSQL 安全
MongoDB分布式存储数据库系列(三)------用户与权限管理
Mongodb 作为时下最为热门的数据库,那么其安全验证也是必不可少的
69 0
|
存储 安全 NoSQL
云MongoDB网络安全策略和权限管理体系
阿里云MongoDB在市场上实际使用时,如何保障数据库安全性?又是如何防止数据库受到攻击?本文将带领你了解云数据库MongoDB云环境的网络安全策略和MongoDB自身的权限管理体系。
2913 0
|
1月前
|
存储 NoSQL MongoDB
MongoDB如何创建数据库
MongoDB如何创建数据库
|
4天前
|
存储 NoSQL 关系型数据库
【MongoDB 专栏】MongoDB 与传统关系型数据库的比较
【5月更文挑战第10天】本文对比了MongoDB与传统关系型数据库在数据模型、存储结构、扩展性、性能、事务支持、数据一致性和适用场景等方面的差异。MongoDB以其灵活的文档模型、优秀的扩展性和高性能在处理非结构化数据和高并发场景中脱颖而出,而关系型数据库则在事务处理和强一致性上更具优势。两者各有适用场景,选择应根据实际需求来定。随着技术发展,两者正相互融合,共同构建更丰富的数据库生态。
【MongoDB 专栏】MongoDB 与传统关系型数据库的比较
|
8天前
|
存储 NoSQL 关系型数据库
MongoDB非关系型数据库实战
【5月更文挑战第6天】MongoDB,流行的NoSQL数据库,以其灵活的数据模型和高性能备受青睐。本文介绍了MongoDB的基础,包括文档型数据库特性、安装配置、数据操作。通过电商订单管理的实战案例,展示了MongoDB在处理复杂数据结构和大规模数据时的优势,适用于电商、游戏、视频直播等场景。MongoDB的索引、全文搜索和地理空间功能进一步增强了其实用性。注意性能优化和扩展性以确保系统稳定性和可靠性。
|
15天前
|
弹性计算 NoSQL Shell
一键安装 MongoDB 数据库脚本
【4月更文挑战第29天】
18 4
|
20天前
|
NoSQL MongoDB 数据库
MongoDB数据恢复—MongoDB数据库文件被破坏的数据恢复案例
服务器数据恢复环境: 一台Windows Server操作系统服务器,服务器上部署MongoDB数据库。 MongoDB数据库故障&检测: 工作人员在未关闭MongoDB数据库服务的情况下,将数据库文件拷贝到其他分区。拷贝完成后将原MongoDB数据库所在分区进行了格式化操作,然后将数据库文件拷回原分区,重新启动MongoDB服务,服务无法启动。

相关产品

  • 云数据库 MongoDB 版