权限管理
权限管理
IoTDB 提供了权限管理功能,用于对数据和集群系统执行精细的访问控制,保障数据与系统安全。本篇介绍了 IoTDB 表模型中权限模块的基本概念、用户定义、权限管理、鉴权逻辑与功能用例。
1. 基本概念
1.1 用户
用户即数据库的合法使用者。一个用户与一个唯一的用户名相对应,并且拥有密码作为身份验证的手段。一个人在使用数据库之前,必须先提供合法的(即存于数据库中的)用户名与密码。
1.2 权限
数据库提供多种操作,但并非所有的用户都能执行所有操作。如果一个用户可以执行某项操作,则称该用户有执行该操作的权限。
1.3 角色
角色是若干权限的集合,并且有一个唯一的角色名作为标识符。角色通常和一个现实身份相对应(例如交通调度员),而一个现实身份可能对应着多个用户。这些具有相同现实身份的用户往往具有相同的一些权限,角色就是为了能对这样的权限进行统一的管理的抽象。
1.4 默认用户与角色
安装初始化后的 IoTDB 中有一个默认用户 root,默认密码为 root。该用户为管理员用户,拥有所有权限,无法被赋予、撤销权限,也无法被删除,数据库内仅有一个管理员用户。一个新创建的用户或角色不具备任何权限。
2. 权限列表
IoTDB 表模型主要有两类权限:全局权限、数据权限。
2.1 全局权限
全局权限包含用户管理和角色管理。
下表描述了全局权限的种类:
权限名称 | 描述 |
---|---|
MANAGE_USER | - 允许用户创建用户 - 允许用户删除用户 - 允许用户修改用户密码 - 允许用户查看用户的权限信息 - 允许用户列出所有用户 |
MANAGE_ROLE | - 允许用户创建角色 - 允许用户删除角色 - 允许用户查看角色的权限信息 - 允许用户将角色授予某个用户或撤销 - 允许用户列出所有角色 |
2.2 数据权限
数据权限由权限类型和范围组成。
权限类型包括:CREATE(创建权限),DROP(删除权限),ALTER(修改权限),SELECT(查询数据权限),INSERT(插入/更新数据权限),DELETE(删除数据权限)。
范围包括:ANY(系统范围内),DATABASE(数据库范围内),TABLE(单个表)。
- 作用于 ANY 的权限会影响所有数据库和表。
- 作用于数据库的权限会影响该数据库及其所有表。
- 作用于表的权限仅影响该表。
范围生效说明:执行单表操作时,数据库会匹配用户权限与数据权限范围。例如,用户尝试向 DATABASE1.TABLE1 写入数据时,系统会依次检查用户是否有对 ANY、DATABASE1或 DATABASE1.TABLE1 的写入权限,直到匹配成功或者匹配失败。
权限类型、范围及效果逻辑关系如下表所示:
权限类型 | 权限范围(层级) | 权限效果 |
---|---|---|
CREATE | ANY | 允许创建任意表、创建任意数据库 |
数据库 | 允许用户在该数据库下创建表;允许用户创建该名称的数据库 | |
表 | 允许用户创建该名称的表 | |
DROP | ANY | 允许删除任意表、删除任意数据库 |
数据库 | 允许用户删除该数据库;允许用户删除该数据库下的表 | |
表 | D允许用户删除该表 | |
ALTER | ANY | 允许修改任意表的定义、任意数据库的定义 |
数据库 | 允许用户修改数据库的定义,允许用户修改数据库下表的定义 | |
表 | 允许用户修改表的定义 | |
SELECT | ANY | 允许查询系统内任意数据库中任意表的数据 |
数据库 | 允许用户查询该数据库中任意表的数据 | |
表 | 允许用户查询该表中的数据。执行多表查询时,数据库仅展示用户有权限访问的数据。 | |
INSERT | ANY | 允许任意数据库的任意表插入/更新数据 |
数据库 | 允许用户向该数据库范围内任意表插入/更新数据 | |
表 | 允许用户向该表中插入/更新数据 | |
DELETE | ANY | 允许删除任意表的数据 |
数据库 | 允许用户删除该数据库范围内的数据 | |
表 | 允许用户删除该表中的数据 |
3. 用户、角色管理
- 创建用户(需 MANAGE_USER 权限)
CREATE USER <USERNAME> <PASSWORD>
eg: CREATE USER user1 'passwd'
- 用户名约束:4~32个字符,支持使用英文大小写字母、数字、特殊字符
(!@#$%^&*()_+-=)
,用户无法创建和管理员用户同名的用户。 - 密码约束:4~32个字符,可使用大写小写字母、数字、特殊字符
(!@#$%^&*()_+-=)
,密码默认采用 MD5 进行加密。
- 更新密码
用户可以更新自己的密码,但更新其他用户密码需要具备 MANAGE_USER 权限。
ALTER USER <USERNAME> SET PASSWORD <password>
eg: ALTER USER tempuser SET PASSWORD 'newpwd'
- 删除用户(需 MANAGE_USER 权限)
DROP USER <USERNAME>
eg: DROP USER user1
- 创建角色 (需 MANAGE_ROLE 权限)
CREATE ROLE <ROLENAME>
eg: CREATE ROLE role1
角色名约束:4~32个字符,支持使用英文大小写字母、数字、特殊字符(!@#$%^&*()_+-=)
,用户无法创建和管理员用户同名的角色。
- 删除角色 (需 MANAGE_ROLE 权限)
DROP ROLE <ROLENAME>
eg: DROP ROLE role1
- 赋予用户角色 (需 MANAGE_ROLE 权限)
GRANT ROLE <ROLENAME> TO <USERNAME>
eg: GRANT ROLE admin TO user1
- 移除用户角色 (需 MANAGE_ROLE 权限)
REVOKE ROLE <ROLENAME> FROM <USERNAME>
eg: REVOKE ROLE admin FROM user1
- 列出所有用户(需 MANAGE_USER 权限)
LIST USER
- 列出所有的角色 (需 MANAGE_ROLE 权限)
LIST ROLE
- 列出指定角色下所有用户(需 MANAGE_USER 权限)
LIST USER OF ROLE <ROLENAME>
eg: LIST USER OF ROLE roleuser
- 列出指定用户下的所有角色
用户可以列出自己的角色,但列出其他用户的角色需要拥有 MANAGE_ROLE 权限。
LIST ROLE OF USER <USERNAME>
eg: LIST ROLE OF USER tempuser
- 列出用户所有权限
用户可以列出自己的权限信息,但列出其他用户的权限需要拥有 MANAGE_USER 权限。
LIST PRIVILEGES OF USER <USERNAME>
eg: LIST PRIVILEGES OF USER tempuser
- 列出角色所有权限
用户可以列出自己具有的角色的权限信息,列出其他角色的权限需要有 MANAGE_ROLE 权限。
LIST PRIVILEGES OF ROLE <ROLENAME>
eg: LIST PRIVILEGES OF ROLE actor
4. 权限管理
IoTDB支持通过如下三种途径进行用户授权和撤销权限:
超级管理员直接授予或撤销
拥有GRANT OPTION权限的用户授予或撤销
通过角色授予或撤销(由超级管理员或具备MANAGE_ROLE权限的用户操作角色)
在IoTDB 表模型中,授权或撤销权限时需遵循以下原则:
授权/撤销全局权限时,无需指定权限的范围。
授予/撤销数据权限时,需要指定权限类型和权限范围。在撤销权限时只会撤销指定的权限范围,不会受权限范围包含关系的影响。
允许对尚未创建的数据库或表提前进行权限规划和授权。
允许重复授权/撤销权限。
WITH GRANT OPTION: 允许用户在授权范围内管理权限。用户可以授予或撤销其他用户在该范围内的权限。
4.1 授予权限
- 给用户授予管理用户的权限
GRANT MANAGE_USER TO USER <USERNAME>
eg: GRANT MANAGE_USER TO USER TEST_USER
- 给用户授予创建数据库及在数据库范围内创建表的权限,且允许用户在该范围内管理权限
GRANT CREATE ON DATABASE <DATABASE> TO USER <USERNAME> WITH GRANT OPTION
eg: GRANT CREATE ON DATABASE TESTDB TO USER TEST_USER WITH GRANT OPTION
- 给角色授予查询数据库的权限
GRANT SELECT ON DATABASE <DATABASE>TO ROLE <ROLENAME>
eg: GRANT SELECT ON DATABASE TESTDB TO ROLE TEST_ROLE
- 给用户授予查询表的权限
GRANT SELECT ON <DATABASE>.<TABLENAME> TO USER <USERNAME>
eg: GRANT SELECT ON TESTDB.TESTTABLE TO USER TEST_USER
- 给角色授予查询所有数据库及表的权限
GRANT SELECT ON ANY TO ROLE <ROLENAME>
eg: GRANT SELECT ON ANY TO ROLE TEST_ROLE
- ALL 语法糖:ALL 表示对象范围内所有权限,可以使用 ALL 字段灵活地授予权限。
GRANT ALL TO USER TESTUSER
-- 将用户可以获取的所有权限授予给用户,包括全局权限和 ANY 范围的所有数据权限
GRANT ALL ON ANY TO USER TESTUSER
-- 将 ANY 范围内可以获取的所有权限授予给用户,执行该语句后,用户将拥有在所有数据库上的所有数据权限
GRANT ALL ON DATABASE TESTDB TO USER TESTUSER
-- 将 DB 范围内可以获取的所有权限授予给用户,执行该语句后,用户将拥有在该数据库上的所有数据权限
GRANT ALL ON TABLE TESTTABLE TO USER TESTUSER
-- 将 TABLE 范围内可以获取的所有权限授予给用户,执行该语句后,用户将拥有在该表上的所有数据权限
4.2 撤销权限
- 取消用户管理用户的权限
REVOKE MANAGE_USER FROM USER <USERNAME>
eg: REVOKE MANAGE_USER FROM USER TEST_USER
- 取消用户创建数据库及在数据库范围内创建表的权限
REVOKE CREATE ON DATABASE <DATABASE> FROM USER <USERNAME>
eg: REVOKE CREATE ON DATABASE TEST_DB FROM USER TEST_USER
- 取消用户查询表的权限
REVOKE SELECT ON <DATABASE>.<TABLENAME> FROM USER <USERNAME>
eg: REVOKE SELECT ON TESTDB.TESTTABLEFROM USER TEST_USER
- 取消用户查询所有数据库及表的权限
REVOKE SELECT ON ANY FROM USER <USERNAME>
eg: REVOKE SELECT ON ANY FROM USER TEST_USER
- ALL 语法糖:ALL 表示对象范围内所有权限,可以使用 ALL 字段灵活地撤销权限。
REVOKE ALL FROM USER TESTUSER
-- 取消用户所有的全局权限以及 ANY 范围的所有数据权限
REVOKE ALL ON ANY FROM USER TESTUSER
-- 取消用户 ANY 范围的所有数据权限,不会影响 DB 范围和 TABLE 范围的权限
REVOKE ALL ON DATABASE TESTDB FROM USER TESTUSER
-- 取消用户在 DB 上的所有数据权限,不会影响 TABLE 权限
REVOKE ALL ON TABLE TESTDB FROM USER TESTUSER
-- 取消用户在 TABLE 上的所有数据权限
4.3 查看用户权限
每个用户都有一个权限访问列表,标识其获得的所有权限。可使用 LIST PRIVILEGES OF USER <USERNAME>
语句查看某个用户或角色的权限信息,输出格式如下:
ROLE | SCOPE | PRIVIVLEGE | WITH GRANT OPTION |
---|---|---|---|
DB1.TB1 | SELECT | FALSE | |
MANAGE_ROLE | TRUE | ||
ROLE1 | DB2.TB2 | UPDATE | TRUE |
ROLE1 | DB3.* | DELETE | FALSE |
ROLE1 | *.* | UPDATE | TRUE |
其中:
ROLE
列:如果为空,则表示为该用户的自身权限。如果不为空,则表示该权限来源于被授予的角色。SCOPE
列:表示该用户/角色的权限范围,表范围的权限表示为DB.TABLE
,数据库范围的权限表示为DB.*
, ANY 范围的权限表示为*.*
。PRIVIVLEGE
列:列出具体的权限类型。WITH GRANT OPTION
列:如果为 TRUE,表示用户可以将自己的权限授予他人。- 用户或者角色可以同时具有树模型和表模型的权限,但系统会根据当前连接的模型来显示相应的权限,另一种模型下的权限则不会显示。
5. 示例
以 示例数据 内容为例,两个表的数据可能分别属于 bj、sh 两个数据中心,彼此间不希望对方获取自己的数据库数据,因此我们需要将不同的数据在数据中心层进行权限隔离。
5.1 创建用户
使用 CREATE USER <USERNAME> <PASSWORD>
创建用户。例如,可以使用具有所有权限的root用户为 ln 和 sgcc 集团创建两个用户角色,名为 bj_write_user
, sh_write_user
,密码均为 write_pwd
。SQL 语句为:
CREATE USER bj_write_user 'write_pwd'
CREATE USER sh_write_user 'write_pwd'
使用展示用户的 SQL 语句:
LIST USER
可以看到这两个已经被创建的用户,结果如下:
+-------------+
| User|
+-------------+
|bj_write_user|
| root|
|sh_write_user|
+-------------+
5.2 赋予用户权限
虽然两个用户已经创建,但是不具有任何权限,因此并不能对数据库进行操作,例如使用 bj_write_user
用户对 table1 中的数据进行写入,SQL 语句为:
IoTDB> INSERT INTO table1(region, plant_id, device_id, model_id, maintenance, time, temperature, humidity, status, arrival_time) VALUES ('北京', '1001', '100', 'A', '180', '2025-03-26 13:37:00', 190.0, 30.1, false, '2025-03-26 13:37:34')
系统不允许用户进行此操作,会提示错误:
IoTDB> INSERT INTO table1(region, plant_id, device_id, model_id, maintenance, time, temperature, humidity, status, arrival_time) VALUES ('北京', '1001', '100', 'A', '180', '2025-03-26 13:37:00', 190.0, 30.1, false, '2025-03-26 13:37:34')
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: database is not specified
IoTDB> use database1
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 803: Access Denied: DATABASE database1
root 用户使用 GRANT <PRIVILEGES> ON <DATABASE.TABLE> TO USER <USERNAME>
语句赋予用户bj_write_user
对 table1 的写入权限,例如:
GRANT INSERT ON database1.table1 TO USER bj_write_user
使用bj_write_user
再尝试写入数据
IoTDB> use database1
Msg: The statement is executed successfully.
IoTDB:database1> INSERT INTO table1(region, plant_id, device_id, model_id, maintenance, time, temperature, humidity, status, arrival_time) VALUES ('北京', '1001', '100', 'A', '180', '2025-03-26 13:37:00', 190.0, 30.1, false, '2025-03-26 13:37:34')
Msg: The statement is executed successfully.
5.3 撤销用户权限
授予用户权限后,可以使用 REVOKE <PRIVILEGES> ON <DATABASE.TABLE> FROM USER <USERNAME>
来撤销已经授予用户的权限。例如,用root用户撤销bj_write_user
和sh_write_user
的权限:
REVOKE INSERT ON database1.table1 FROM USER bj_write_user
REVOKE INSERT ON database1.table2 FROM USER sh_write_user
撤销权限后,bj_write_user
就没有向table1写入数据的权限了。
IoTDB:database1> INSERT INTO table1(region, plant_id, device_id, model_id, maintenance, time, temperature, humidity, status, arrival_time) VALUES ('北京', '1001', '100', 'A', '180', '2025-03-26 13:37:00', 190.0, 30.1, false, '2025-03-26 13:37:34')
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 803: Access Denied: No permissions for this operation, please add privilege INSERT ON database1.table1