云数据库 SelectDB 版的权限管理系统借鉴了MySQL的权限管理机制,实现了表级别细粒度的权限控制,并支持基于角色的权限访问控制和白名单机制。本文介绍云数据库 SelectDB 版包含的权限管理系统的背景和具备的权限管理能力,及一些使用时的注意事项。
权限说明
权限类型
权限名称 | 说明 |
GRANT_PRIV | 权限变更权限。 允许执行包括授权、撤权、添加、删除和变更用户或角色等操作。 |
SELECT_PRIV | 对数据库、表的只读权限。 |
LOAD_PRIV | 对数据库、表的写权限。包括Load、Insert、Delete等。 |
ALTER_PRIV | 对数据库、表的更改权限。包括重命名数据库和表,添加、删除或变更列,添加或删除分区等操作。 |
CREATE_PRIV | 创建数据库、表、视图的权限。 |
DROP_PRIV | 删除数据库、表、视图的权限。 |
USAGE_PRIV | 资源的使用权限。 |
权限层级
根据权限适用范围的不同,库表的权限分为以下层级:
权限级别 | 说明 |
GLOBAL LEVEL 全局权限 | 通过GRANT语句授予的 |
CATALOG LEVEL 数据目录级权限 | 通过GRANT语句授予的 |
DATABASE LEVEL 数据库级权限 | 通过GRANT语句授予的 |
TABLE LEVEL 表级权限 | 通过GRANT语句授予的 |
资源的权限分为以下两个层级:
权限级别 | 说明 |
GLOBAL LEVEL 全局权限 | 通过GRANT语句授予的 |
RESOURCE LEVEL 资源级权限 | 通过GRANT语句授予的 |
ADMIN/GRANT权限说明
ADMIN_PRIV和GRANT_PRIV权限同时拥有授予权限的权限,较为特殊。ADMIN_PRIV和GRANT_PRIV权限相关的操作说明如下:
CREATE USER
拥有ADMIN权限,或GLOBAL和DATABASE层级的GRANT权限的用户可以创建新用户。
DROP USER
拥有ADMIN权限或全局层级的GRANT权限的用户可以删除用户。
CREATE/DROP ROLE
拥有ADMIN权限或全局层级的GRANT权限的用户可以创建角色。
GRANT/REVOKE
拥有ADMIN权限,或者GLOBAL层级GRANT权限的用户,可以授予或撤销任意用户的权限。
拥有CATALOG层级GRANT权限的用户,可以授予或撤销任意用户对指定CATALOG的权限。
拥有DATABASE层级GRANT权限的用户,可以授予或撤销任意用户对指定数据库的权限。
拥有TABLE层级GRANT权限的用户,可以授予或撤销任意用户对指定数据库中指定表的权限。
SET PASSWORD
拥有ADMIN权限,或者GLOBAL层级GRANT权限的用户,可以设置任意用户的密码。
普通用户可以设置自己对应的UserIdentity的密码。自己对应的UserIdentity可以通过
SELECT CURRENT_USER();
命令查看。拥有非GLOBAL层级GRANT权限的用户,不可以设置已存在用户的密码,仅能在创建用户时指定密码。
用户属性列表
部分与用户相关的属性如下表所示:
属性名 | 说明 |
cpu_resource_limit | 限制查询的CPU资源。详见会话变量 |
default_load_cluster | 默认的导入Cluster。 |
exec_mem_limit | 限制查询的内存使用。详见会话变量 |
insert_timeout | 指定用户INSERT操作的超时限制。 |
max_query_instances | 用户同一时间点执行查询可以使用的执行单元个数。 |
max_user_connections | 最大连接数。 |
query_timeout | 指定用户的查询超时限制。 |
resource_tags | 指定用户的资源标签限制。 |
sql_block_rules | 设置SQL Block Rules。设置后,用户发送的查询如果匹配规则,则会被拒绝执行。 |
如果某个用户属性(user property)在变量(variable)中也存在,例如query_timeout
,生效的优先级次序是:session variable
>user property
>global variable
>default value
。较高优先级的变量未设置时,会自动采用下一个优先级的数值。
权限操作
操作名称 | 操作关键字 | 语法 |
创建用户 | CREATE USER |
|
删除用户 | DROP USER |
|
授权 | GRANT |
|
撤权 | REVOKE |
|
创建角色 | CREATE ROLE |
|
删除角色 | DROP ROLE |
|
查看当前(所有)用户权限 | SHOW (ALL)GRANTS |
|
查看已创建的角色 | SHOW ROLES |
|
查看用户属性 | SHOW PROPERTY |
|
设置用户属性 | SET PROPERTY |
|
参数说明
参数 | 说明 |
[password_policy] | 指定密码认证登录相关策略,具体策略如下。
|
操作示例
示例1:创建用户
test_user
且密码为123456,允许从'172.10.XX.XX'地址登录。CREATE USER test_user@'172.10.XX.XX' IDENTIFIED BY '123456';
示例2:删除用户
test_user@'172.10.XX.XX'
。DROP USER 'test_user'@'172.10.XX.XX'
示例3:授予用户
test_user@'172.10.XX.XX'
表test_ctl.test_db.test_table
的读取、修改和导入权限。GRANT SELECT_PRIV,ALTER_PRIV,LOAD_PRIV ON test_ctl.test_db.test_table TO 'test_user'@'172.10.XX.XX';
示例4:撤销用户
test_user
数据库test_db的读取权限。REVOKE SELECT_PRIV ON test_db.* FROM 'test_user'@'172.10.XX.XX';
示例5:创建角色
test_role
。CREATE ROLE test_role;
示例6:删除角色
test_role
。DROP ROLE test_role;
示例7:将数据库
test_ctl.test_db
的所有表的导入权限授予于角色test_role
。GRANT LOAD_PRIV ON test_ctl.test_db.* TO ROLE 'test_role';
示例8:将用户
test_user@'172.10.XX.XX'
的角色修改为test_role
。GRANT "test_role" TO test_user@'172.10.XX.XX';
示例9:查看用户
test_user@'%'
的权限。SHOW GRANTS FOR test_user@'%';
示例10:查看用户
test_user
的属性。# 查看用户的全部属性 SHOW PROPERTY FOR 'test_user'; # 使用LIKE表达式查看用户的具体属性 SHOW PROPERTY FOR 'test_user' LIKE '%max_user_connections%';
示例11:设置用户
test_user
的属性。SET PROPERTY FOR 'test_user' 'max_user_connections' = '1000';
最佳实践
常见权限系统的使用场景如下:
场景一
集群的使用者分为管理员(Admin)、开发工程师(RD)和用户(Client)。其中管理员拥有整个集群的所有权限,主要负责集群的搭建、节点管理等。开发工程师负责业务建模,包括建库建表、数据的导入和修改等。用户访问不同的数据库和表来获取数据。
在这种场景下,可以为管理员赋予ADMIN权限或GRANT权限。对RD赋予对任意或指定数据库表的 CREATE、DROP、ALTER、LOAD、SELECT权限。对Client赋予对任意或指定数据库表SELECT权限。同时,也可以通过创建不同的角色,来简化对多个用户的授权操作。
场景二
一个集群内有多个业务,每个业务可能使用一个或多个数据。每个业务需要管理自己的用户。在这种场景下,管理员用户可以为每个数据库创建一个拥有DATABASE层级GRANT权限的用户。该用户仅可以对用户进行指定的数据库的授权。
场景三
云数据库 SelectDB 版本身不支持黑名单,只有白名单功能,但可以通过某些方式来模拟黑名单。假设先创建了名为
test_user1@'192.%'
的用户,表示允许来自192.*
的用户登录。此时如果想禁止来自192.168.XX.XX
的用户登录。则可以再创建一个用户test_user2@'192.168.XX.XX'
的用户,并设置一个新的密码。因为192.168.XX.XX
的优先级高于192.%
,所以来自192.168.XX.XX
将不能再使用旧密码进行登录。
权限注意事项
实例初始化时,会自动创建如下角色和用户:
operator角色:该角色为运维操作角色,拥有Node_priv和Admin_priv权限,即对云数据库 SelectDB 版的所有权限,允许从任意节点登录。仅实例内置的root用户(root@'%')拥有该角色。
admin角色:该角色为管理角色,拥有Admin_priv权限,即除节点变更以外的所有权限,允许从任意节点登录。实例初始化会自动创建一个该角色的用户admin(admin@'%'),支持创建多个该角色的用户。
不支持删除或更改默认创建的角色或用户的权限。
忘记admin密码。如果忘记了admin密码无法登录,可以在管控平台上重置admin密码,详情请参见重置实例admin密码。
ADMIN_PRIV权限只能在GLOBAL层级授予或撤销。
拥有GLOBAL层级GRANT_PRIV等同于拥有ADMIN_PRIV,因为该层级的GRANT_PRIV有授予任意权限的权限,请谨慎使用。
通过
SELECT current_user();
和SELECT user();
可以分别查看current_user
和user
。其中current_user
表示当前用户是以哪种身份通过认证系统的,而user
则是用户当前实际的user_identity
。所有的权限都是赋予某一个current_user
的,真实用户拥有对应的current_user
的所有权限。举例说明:假设创建了
user1@'192.%'
这个用户,但是来自192.168.XX.XX
的用户user1
登录了系统,则此时的current_user
为user1@'192.%'
,而user
为user1@'192.168.XX.XX'
。
常见问题
Q:如何解决在创建用户并且进行授权时,遇到域名与IP冲突或重复IP冲突的问题?
A:执行DROP USER
删除出现冲突的用户后重新创建用户,即可解决问题。
域名与IP冲突:
删除该用户后,创建新用户并且授权,示例如下。
CREATE USER test_user@['domain']; GRANT SELECT_PRIV ON.TO test_user@['domain'];
例如,该domain被DNS解析为两个IP:IP1和IP2。
对用户
test_user@['domain']
进行一次单独授权的访问IP1授权,示例如下。GRANT ALTER_PRIV ON.TO test_user@'IP1';
则
test_user@'IP1'
的权限会被从SELECT_PRIV修改为ALTER_PRIV,且允许访问的IP变更为IP1,再次变更test_user@['domain']
的权限时,test_user@'IP1'
也不会跟随改变。
重复IP冲突:
删除该用户后,创建新用户,示例如下。
CREATE USER test_user@'%' IDENTIFIED BY "12345"; CREATE USER test_user@'192.%' IDENTIFIED BY "abcde";
在优先级上,'192.%'优先于'%'。因此,当用户
test_user
从192.168.XX.XX这台机器尝试使用密码'12345'登录云数据库 SelectDB 版时会被拒绝。