权限管理


  • 管理员可使用 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 函数列出
    是否有权创建和删除管理员、用户、组
    是否有权赋予和禁止管理员、用户、组的权限
    是否有权创建和删除函数视图
    是否有权删除其他用户提交的任务

分布式数据库权限管理

创建用户

  1. 管理员登录:

    login(`admin, `123456)

    该管理员登录名和密码为系统默认。

  2. 创建用户(以USR1为例):

    createUser("USR1","AB123!@")
  3. 赋予用户可读任何 DFS 数据表的权限:

    grant("USR1",TABLE_READ,"*")
  4. 禁止用户 USR1 创建或删除数据库:

    deny("USR1",DB_MANAGE)
  5. 创建组,并把用户加入到该组(该例子中,组名为GP1):

    createGroup("GP1", "USR1")
  6. 赋予 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"。

共享内存表权限设置

共享内存表会被共享到所有会话中,因此也会有权限管理的需求。系统支持对共享内存表进行表写入和表读取的权限管理,语法与数据库表权限管理一致。

  1. 创建管理员 USR6

    createUser("USR6","JI3564^",,true)
  2. 登录 USR6 并创建共享内存表 st1, 赋予用户 USR5 读取该表的权限:

    login(`USR6, "JI3564^")
    
    share table(1:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]) as st1
    grant("USR5", TABLE_READ, "st1")
  3. 通过 getUserAccess 函数查看用户权限。以下命令返回的 TABLE_READ_allowed 列可以看到,用户 USR5 至此已经拥有了表 st1 的读权限。

    getUserAccess("USR5")

    需要注意的是,在 USR6 使用 grant(或 deny)函数进行权限管理之前,任何用户对该表都有读写权限。

    如上对该表进行过第一次权限操作之后,该表自动添加权限限制。此时只有管理员和表创建者 USR6 对该表有读写权限。

  4. 也可以撤销用户 USR5 读取共享内存表的权限:

    revoke("USR5", TABLE_READ, "st1")
  5. 若在建表后希望仅自己和管理员对共享内存表有访问权限,可以使用 addAccessControl 对于表增加权限控制。

    share table(1:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]) as st2
    addAccessControl(st2)

函数视图(function view)权限设置

函数视图提供了一种灵活的方式来控制用户访问数据库和表。在视图的基础上,函数视图提供了函数功能,可以同时访问数据库并进行相关计算。

注意

  • 只有系统管理员有创建和删除函数视图的权限。用户即使不具备读写数据库原始数据的权限,也可通过执行函数视图,间接访问数据库,得到所需计算结果。
  • 如果函数视图和本地的函数重名,调用时系统会解析为本地函数。

赋予用户部分执行权限

在下例中,管理员定义一个函数视图 "countTradeAll",并且赋予用户 USR1 执行视图 "countTradeAll" 的权限。

  1. 管理员定义一个函数视图:

    def countTradeAll(){ 
    
        return exec count(*) from loadTable("dfs://TAQ","Trades") 
    
    }
    
    addFunctionView(countTradeAll) 
    grant("USR1",VIEW_EXEC,"countTradeAll")
  2. 以用户名 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 命令时,系统管理员可以删除其他用户制定的任务,非管理员用户只能删除自己创建的任务。