权限管理
- 管理员可使用 grant/deny/revoke 命令在控制节点上来设置用户或组的权限。
- 用户也可以使用命令 addAccessControl 限制其他用户访问该用户创建的共享内存表或者流数据引擎。使用 addAccessControl 后,其他用户只有被管理员赋予访问权限后,才可访问该用户创建的共享表或者流数据引擎。
角色与权限
用户和组
在权限管理系统中,DolphinDB 引入组的概念,便于对具有相同权限的用户进行权限配置和管理。
一个用户可以属于0,1或多个组,一个组里也可以包括0,1或多个用户。
用户和组都是承载权限的实体。我们可以赋予或禁止一个用户、一个组某项权限。用户最终的实际权限是用户本身的权限,加上所属组的权限的结果(详见1.2 用户权限确定规则)。
DolphinDB 系统通过用户名和密码对用户进行身份校检,通过 login 和 logout 来进行用户的登录和注销管理。 用户可以通过使用 changePwd 来改变自己的登录密码。
管理员
管理员分超级管理员(super admin)和管理员(admin)。
DolphinDB 集群第一次启动时,会自动创建用户名为 "admin",密码为 "123456" 的超级管理员。此管理员拥有所有的权限,且无法被删除。超级管理员 “admin” 无法被删除,其权限也无法被剥夺。
超级管理员可以创建其他用户,对用户进行分组,并选择是否设定为管理员。新创建的管理员、用户和组没有任何权限。管理员可以赋予或禁止其他管理员,用户和组的权限,撤销权限设置。管理员可以通过 resetPwd 修改用户的密码。
管理员可使用的函数或命令有:
- addGroupMember: 添加组成员
- createGroup:创建组
- createUser:创建用户
- deleteGroup :删除组
- deleteGroupMember:删除组成员
- deleteUser:删除用户
- getGroupsByUserId:根据用户编号得到组
- getGroupList:获取组列表
- getUserAccess:获取用户所单独被赋予的权限,不包括用户所属组的权限
- getUsersByGroupId:获取组的用户列表
- getUserList:获取除管理员之外的所有用户名
- resetPwd:重置用户的密码
以下为超级管理员、管理员和普通用户的总结表:
操作 超级管理员 管理员 非管理员用户 是否需要手动创建 否 是 是 初始权限 拥有所有权限 无任何权限 无任何权限 是否可以被删除 否 是 是 是否会被 getUserList 函数列出 否 是 是 是否有权创建和删除管理员、用户、组 是 是 否 是否有权赋予和禁止管理员、用户、组的权限 是 是 否 是否有权创建和删除函数视图 是 是 否 是否有权删除其他用户提交的任务 是 是 否
分布式数据库权限管理
创建用户
管理员登录:
login(`admin, `123456)该管理员登录名和密码为系统默认。
创建用户(以USR1为例):
createUser("USR1","AB123!@")赋予用户可读任何 DFS 数据表的权限:
grant("USR1",TABLE_READ,"*")禁止用户 USR1 创建或删除数据库:
deny("USR1",DB_MANAGE)创建组,并把用户加入到该组(该例子中,组名为GP1):
createGroup("GP1", "USR1")赋予 GP1 组可在数据库"dfs://db1"和"dfs://db2"中创建数据表的权限:
grant("GP1",DBOBJ_CREATE,["dfs://db1","dfs://db2"])
最后用户 USR1 的权限为:
- 可以访问所有的数据表
- 不能创建或删除数据库
- 可以对"dfs://db1"和"dfs://db2"进行创建数据表的操作
通过组权限赋予用户权限
通过组可以方便的设置用户权限:
createUser("USR2", "AB123!@")
createUser("USR3","CD234@#")
createUser("USR4","EF345#$")
createGroup("GP2", ["USR2","USR3","USR4"])
grant("GP2", TABLE_READ, "dfs://TAQ/quotes")
grant("USR4", DB_MANAGE)该例子创建了3个用户(USR2, USR3, USR4)和1个组(GP2),并且这三个用户属于该组。赋予此组可读数据表”dfs://TAQ/quotes" 的权限,同时只赋予用户 USR4 创建和删除数据库的权限。
禁止与撤销权限
可以使用 grant 或 deny 对所有对象(以*代表)赋予或禁止权限。例如,赋予用户 USR3 对于任何 DFS 数据表的读权限:
grant("USR3",TABLE_READ,"*")当 grant 或 deny 所有对象后,若要撤销操作,只能使用 revoke 撤销所有对象的权限,若只撤销某个指定对象的权限,则操作无效:
revoke("USR3",TABLE_READ,"dfs://db1/t1")以上命令无效。
revoke("USR3",TABLE_READ,"*")以上命令取消了用户 USR3 可读任何 DFS 数据表的权限。
与之类似,使用 grant 或 deny 对组赋予或禁止权限后,只能对该组使用 revoke 来取消该权限设置。若对某个组员使用 revoke 来取消该权限,则无法生效。
通过DB_OWNER权限赋予其他用户权限
有 DB_OWNER 权限的用户可以赋予别的用户对自己创建的数据库的权限。
管理员创建了两个用户,USR5 和 USR6,其中用户 USR6 拥有 DB_OWNER 的权限:
createUser(`USR5, "GH456$%")
createUser(`USR6, "JI3564^")
grant(`USR6,DB_OWNER);USR6 创建数据表"dfs://dbMT/dt", 并赋予用户 USR5 读取该数据表的权限:
login(`USR6, "JI3564^");
db = database("dfs://dbMT", VALUE, 1..10)
t=table(1..1000 as id, rand(100, 1000) as x)
dt = db.createTable(t, "dt").append!(t)
grant(`USR5, TABLE_READ, "dfs://dbMT/dt");尽管用户 USR5 之前没有被系统管理员赋予任何权限,但是 USR5 最后的权限为:可以访问 USR6 创建的数据表"dfs://dbMT/dt"。
共享内存表权限设置
共享内存表会被共享到所有会话中,因此也会有权限管理的需求。系统支持对共享内存表进行表写入和表读取的权限管理,语法与数据库表权限管理一致。
创建管理员 USR6
createUser("USR6","JI3564^",,true)登录 USR6 并创建共享内存表 st1, 赋予用户 USR5 读取该表的权限:
login(`USR6, "JI3564^") share table(1:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]) as st1 grant("USR5", TABLE_READ, "st1")通过 getUserAccess 函数查看用户权限。以下命令返回的 TABLE_READ_allowed 列可以看到,用户 USR5 至此已经拥有了表 st1 的读权限。
getUserAccess("USR5")需要注意的是,在 USR6 使用 grant(或 deny)函数进行权限管理之前,任何用户对该表都有读写权限。
如上对该表进行过第一次权限操作之后,该表自动添加权限限制。此时只有管理员和表创建者 USR6 对该表有读写权限。
也可以撤销用户 USR5 读取共享内存表的权限:
revoke("USR5", TABLE_READ, "st1")若在建表后希望仅自己和管理员对共享内存表有访问权限,可以使用 addAccessControl 对于表增加权限控制。
share table(1:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]) as st2 addAccessControl(st2)
函数视图(function view)权限设置
函数视图提供了一种灵活的方式来控制用户访问数据库和表。在视图的基础上,函数视图提供了函数功能,可以同时访问数据库并进行相关计算。
注意:
- 只有系统管理员有创建和删除函数视图的权限。用户即使不具备读写数据库原始数据的权限,也可通过执行函数视图,间接访问数据库,得到所需计算结果。
- 如果函数视图和本地的函数重名,调用时系统会解析为本地函数。
赋予用户部分执行权限
在下例中,管理员定义一个函数视图 "countTradeAll",并且赋予用户 USR1 执行视图 "countTradeAll" 的权限。
管理员定义一个函数视图:
def countTradeAll(){ return exec count(*) from loadTable("dfs://TAQ","Trades") } addFunctionView(countTradeAll) grant("USR1",VIEW_EXEC,"countTradeAll")以用户名 USR1 登录,执行视图 "countTradeAll"
countTradeAll()
在此例中,虽然用户 USR1 没有访问表"dfs://TAQ/Trades"的权限,但是可以运行函数视图 "countTradeAll" 获取表的行数。
赋予用户部分参数使用权限
函数视图也可以带参数。用户在使用的时候可以输入参数获取相应的结果。下面的例子,我们创建一个函数视图,获取某一个股票在某一天的所有交易记录。
def getTrades(s, d){
return select * from loadTable("dfs://TAQ","Trades") where sym=s, date=d
}
addFunctionView(getTrades)
grant("USR1",VIEW_EXEC,"getTrades")同样在此例中,用户 USR1 没有访问表"dfs://TAQ/Trades"的权限,但是可以执行视图 “getTrades”,指定股票代码 IBM 和日期 2018.07.09,获得 IBM 在 2018.07.09 这一天的所有交易记录:
getTrades("IBM", 2018.07.09)定时作业权限设置
定时作业是指用户指定在特定的时间,以特定的频率执行一系列任务,多用于批处理类业务场景。
login("USR1","AB123!@")
def readTable(){
read_t1=loadTable("dfs://db1","t1")
return exec count(*) from read_t1
}
scheduleJob("readTableJob","read DFS table",readTable,minute(now()),date(now()),date(now())+1,'D');不管 USR1 有没有读"dfs://db1/t1"的权限,"readTable" 任务都能设置成功。
在 "readTable" 任务实际运行时,如果用户 USR1 有读"dfs://db1/t1"的权限,则成功执行,否则鉴权失败。
另外,使用 deleteScheduledJob 命令时,系统管理员可以删除其他用户制定的任务,非管理员用户只能删除自己创建的任务。
