Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

用户及细粒度权限管理 #234

Merged
merged 6 commits into from
Apr 12, 2024
Merged

用户及细粒度权限管理 #234

merged 6 commits into from
Apr 12, 2024

Conversation

wy1433
Copy link
Contributor

@wy1433 wy1433 commented Apr 12, 2024

与 MySQL 安全特性差异

除以下功能外,支持与 MySQL 5.6 类似的安全特性。

  • 不支持主机名
  • 不支持列级别权限设置。
  • 不支持密码过期,最后一次密码变更记录以及密码生存期。
  • 不支持权限属性 max_questionsmax_updated 以及 max_user_connections
  • 不支持密码验证。
  • 不支持证书鉴权。
  • 不支持用户代理。

可用的身份验证插件

支持多种身份验证方式。通过使用 CREATE USER 语句和 ALTER USER 语句,即可创建新用户或更改权限系统内的已有用户。身份验证方式与 MySQL 兼容,其名称与 MySQL 保持一致。

目前仅支持MySQL 5.6 默认的mysql_native_password身份验证方式。

用户管理

兼容MySQL语法的用户管理。

1. namespace 管理

1.1 create namespace

语法:

CREATE NAMESPACE [IF NOT EXISTS] 
namespace_name [namespace_options]

namespace_name:
    identifier

namespace_options:
    namespace_option [[,] namespace_option] ...

namespace_option: {
    QUOTA [=] value
  | RESOURCE_TAG [=] 'string'
}
MySQL [TestDB]> create namespace ns quota = 1000 resource_tag "pay";
Query OK, 0 rows affected (0.00 sec)

1.2 show namespace

MySQL [TestDB]> show namespaces;
+--------------+----------------+---------+-----------+--------------+
| namespace_id | namespace_name | version | quota     | resource_tag |
+--------------+----------------+---------+-----------+--------------+
|            3 |             ns |       1 |      1000 | pay          |
|            2 |       INTERNAL |       1 | 104857600 | NULL         |
|            1 |           TEST |       1 | 104857600 | NULL         |
+--------------+----------------+---------+-----------+--------------+
3 rows in set (0.00 sec)

1.3 alter namespace

MySQL [TestDB]> alter namespace ns quota=1024000, resource_tag="test";
Query OK, 0 rows affected (0.00 sec)

MySQL [TestDB]> show namespaces;
+--------------+----------------+---------+-----------+--------------+
| namespace_id | namespace_name | version | quota     | resource_tag |
+--------------+----------------+---------+-----------+--------------+
|            3 |             ns |       2 |   1024000 | test         |
|            2 |       INTERNAL |       1 | 104857600 | NULL         |
|            1 |           TEST |       1 | 104857600 | NULL         |
+--------------+----------------+---------+-----------+--------------+
3 rows in set (0.00 sec)

1.4 drop namespace

MySQL [TestDB]> drop namespace ns;
Query OK, 0 rows affected (0.00 sec)

MySQL [TestDB]> show namespaces;
+--------------+----------------+---------+-----------+--------------+
| namespace_id | namespace_name | version | quota     | resource_tag |
+--------------+----------------+---------+-----------+--------------+
|            2 |       INTERNAL |       1 | 104857600 | NULL         |
|            1 |           TEST |       1 | 104857600 | NULL         |
+--------------+----------------+---------+-----------+--------------+
2 rows in set (0.00 sec)

2. user 管理

2.1 create user

MySQL [TestDB]> create user "test"@"%" IDENTIFIED BY "test123";
Query OK, 0 rows affected (0.00 sec)

2.2 show user

MySQL [TestDB]> show user test;
+----------+----------+----------------+---------+----------+
| Username | Password | Namespace Name | Version | Auth IPs |
+----------+----------+----------------+---------+----------+
| test     | test123  | TEST           | 1       | NULL     |
+----------+----------+----------------+---------+----------+
1 row in set (0.00 sec)

2.3 alter user

MySQL [TestDB]> alter user "test"@"%" IDENTIFIED BY "test456";
Query OK, 0 rows affected (0.00 sec)

MySQL [TestDB]> show user test;
+----------+----------+----------------+---------+----------+
| Username | Password | Namespace Name | Version | Auth IPs |
+----------+----------+----------------+---------+----------+
| test     | test456  | TEST           | 2       | NULL     |
+----------+----------+----------------+---------+----------+
1 row in set (0.00 sec)

2.4 drop user

MySQL [TestDB]> drop user "test";
Query OK, 0 rows affected (0.00 sec)

权限管理

支持 MySQL 5.6 的权限管理系统,包括 MySQL 的语法和权限类型。

本文档主要介绍权限相关操作、各项操作需要的权限以及权限系统的实现。

权限相关操作

授予权限

授予 test 用户对数据库 TestDB 的读权限:

GRANT SELECT ON TestDB.* TO 'test'@'%';

test 用户授予所有数据库,全部权限:

GRANT ALL PRIVILEGES ON *.* TO 'test'@'%';

如果指定的用户不存在,GRANT 语句将报错。

MySQL [TestDB]> grant all on *.* to test1; 
ERROR 1396 (HY000): username not exist

GRANT 还必须精确匹配地授予用户数据库的权限:

收回权限

REVOKE 语句与 GRANT 对应:

REVOKE ALL PRIVILEGES ON `TestDB`.* FROM test;

注意:

REVOKE 收回权限时只做精确匹配,若找不到记录则报错。而 GRANT 授予权限时目前也不支持模糊匹配

如果想将一些特殊的关键字做为表名,可以用反引号包含起来。比如:

CREATE TABLE `select` (id int);
Query OK, 0 rows affected (0.27 sec)

查看为用户分配的权限

SHOW GRANTS 语句可以查看为用户分配了哪些权限。例如:

查看当前用户的权限:

SHOW GRANTS;
+-------------------------------------------------------------+
| Grants for User                                             |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION |
+-------------------------------------------------------------+

或者:

SHOW GRANTS FOR CURRENT_USER();

查看某个特定用户的权限:

SHOW GRANTS FOR 'user'@'host';

例如,创建一个用户 rw_user 并为其授予 TestDB.write_table 表的写权限,和全局读权限。

CREATE TABLE `write_table`(`id` bigint(20), PRIMARY KEY (`id`));
CREATE USER `rw_user` IDENTIFIED BY "rw123";
GRANT SELECT ON *.* TO `rw_user`;
GRANT INSERT, UPDATE ON `TestDB`.`write_table` TO `rw_user`;

查看用户 `rw_user 的权限。

SHOW GRANTS FOR `rw_user`;
+-------------------------------------------------------------+
| Grants for rw_user                                          |
+-------------------------------------------------------------+
| GRANT SELECT ON '*.*'@'%' TO rw_user                        |
| GRANT INSERT, UPDATE ON 'TestDB.write_table'@'%' TO rw_user |
+-------------------------------------------------------------+

各操作需要的权限

已支持的权限控制

权限 允许操作 Meaning and Grantable Levels
ALL [PRIVILEGES] ALL Grant all privileges at specified access level except GRANT OPTION and PROXY.
USAGE NONE Synonym for “no privileges”
SELECT SELECT , UNION Enable use of SELECT. Levels: Global, database, table, column.
INSERT INSERT Enable use of INSERT. Levels: Global, database, table, column.
UPDATE UPDATE Enable use of UPDATE. Levels: Global, database, table, column.
DELETE DELETE , TRUNCATE Enable use of DELETE. Level: Global, database, table.
FILE LOAD Enable the user to cause the server to read or write files. Level: Global.
CREATE CREATE_NAMESPACE, CREATE_DATABASE, CREATE_TABLE Enable database and table creation. Levels: Global, database, table.
DROP DROP_NAMESPACE, DROP_DATABASE, DROP_TABLE Enable databases, tables, and views to be dropped. Levels: Global, database, table.
ALTER MODIFY_NAMESPACE, MODIFY_DATABASE, RENAME_TABLE, ADD_FIELD, DROP_FIELD, RENAME_FIELD, MODIFY_FIELD Enable use of ALTER TABLE. Levels: Global, database, table.
INDEX ADD_INDEX, DROP_INDEX, RENAME_INDEX Enable indexes to be created or dropped. Levels: Global, database, table.
CREATE USER CREATE_USER, DROP_USER, MODIFY_USER Enable use of CREATE USER, DROP USER, RENAME USER, and REVOKE ALL PRIVILEGES. Level: Global.
GRANT OPTION GRANT, REVOKE Enable privileges to be granted to or removed from other accounts. Levels: Global, database, table, routine, proxy.

未支持的权限控制(仅兼容MySQL语法)

权限 Meaning and Grantable Levels
ALTER ROUTINE Enable stored routines to be altered or dropped. Levels: Global, database, routine.
CREATE ROUTINE Enable stored routine creation. Levels: Global, database.
CREATE TABLESPACE Enable tablespaces and log file groups to be created, altered, or dropped. Level: Global.
CREATE TEMPORARY TABLES Enable use of CREATE TEMPORARY TABLE. Levels: Global, database.
CREATE VIEW Enable views to be created or altered. Levels: Global, database, table.
EVENT Enable use of events for the Event Scheduler. Levels: Global, database.
EXECUTE Enable the user to execute stored routines. Levels: Global, database, routine.
LOCK TABLES Enable use of LOCK TABLES on tables for which you have the SELECT privilege. Levels: Global, database.
PROCESS Enable the user to see all processes with SHOW PROCESSLIST. Level: Global.
PROXY Enable user proxying. Level: From user to user.
REFERENCES Enable foreign key creation. Levels: Global, database, table, column.
RELOAD Enable use of FLUSH operations. Level: Global.
REPLICATION CLIENT Enable the user to ask where source or replica servers are. Level: Global.
REPLICATION SLAVE Enable replicas to read binary log events from the source. Level: Global.
SHOW DATABASES Enable SHOW DATABASES to show all databases. Level: Global.
SHOW VIEW Enable use of SHOW CREATE VIEW. Levels: Global, database, table.
SHUTDOWN Enable use of mysqladmin shutdown. Level: Global.
SUPER Enable use of other administrative operations such as CHANGE MASTER TO, KILL, PURGE BINARY LOGS, SET GLOBAL, and mysqladmin debug command. Level: Global.
TRIGGER Enable trigger operations. Levels: Global, database, table.

ALTER

  • 对于所有的 ALTER 语句,均需要用户对所操作的表拥有 ALTER 权限。
  • ALTER...DROPALTER...RENAME TO 外,均需要对所操作表拥有 INSERTCREATE 权限。
  • 对于 ALTER...DROP 语句,需要对表拥有 DROP 权限。
  • 对于 ALTER...RENAME TO 语句,需要对重命名前的表拥有 DROP 权限,对重命名后的表拥有 CREATEINSERT 权限。

注意:

根据 MySQL 5.7 文档中的说明,对表进行 ALTER 操作需要 INSERTCREATE 权限,但在 MySQL 5.7.25 版本实际情况中,该操作仅需要 ALTER 权限。目前, ALTER 权限与 MySQL 实际行为保持一致。

CREATE DATABASE

需要拥有全局 CREATE 权限。

CREATE INDEX

需要对所操作的表拥有 INDEX 权限。

CREATE TABLE

需要对要创建的表所在的数据库拥有 CREATE 权限;若使用 CREATE TABLE...LIKE... 需要对相关的表拥有 SELECT 权限。

DROP DATABASE

需要对数据库拥有 DROP 权限。

DROP INDEX

需要对所操作的表拥有 INDEX 权限。

DROP TABLES

需要对所操作的表拥有 DROP 权限。

LOAD DATA

LOAD DATA 对所操作的表拥有 FILE 权限。

TRUNCATE TABLE

需要对所操作的表拥有 DELETE 权限。

RENAME TABLE

需要拥有 ALTER 权限。

SHOW 【TODO】

SHOW CREATE TABLE 需要任意一种权限。

SHOW CREATE VIEW 需要 SHOW VIEW 权限。

SHOW GRANTS 需要拥有对 mysql 数据库的 SELECT 权限。如果是使用 SHOW GRANTS 查看当前用户权限,则不需要任何权限。

SHOW PROCESSLIST 需要 SUPER 权限来显示属于其他用户的连接。

CREATE USER

CREATE USER 需要 CREATE USER 权限

DROP USER

DROP USER 需要 CREATE USER 权限

ALTER USER

ALTER USER 需要 CREATE USER 权限。

GRANT

GRANT 需要 GRANT 权限并且拥有 GRANT 所赋予的权限。

如果在 GRANTS 语句中创建用户,需要有 CREATE USER 权限。

GRANT ROLE 操作需要拥有 SUPER 或者 ROLE_ADMIN 权限。

REVOKE

REVOKE 需要 GRANT 权限并且拥有 REVOKE 所指定要撤销的权限。

REVOKE ROLE 操作需要拥有 SUPER 或者 ROLE_ADMIN 权限。

SET GLOBAL 【TODO】

使用 SET GLOBAL 设置全局变量需要拥有 SUPER 权限。

HANDLE 【TODO】

需要拥有 SUPER 权限。

KILL 【TODO】

使用 KILL 终止其他用户的会话需要拥有 SUPER权限。

生效时机

启动时,将一些权限检查的表加载到内存,之后使用缓存的数据来验证权限。系统会周期性的将授权表从数据库同步到缓存,生效则是由同步的周期决定,目前这个值设定的是 10秒钟。

修改了授权表,如果需要立即生效,可以手动调用:[暂未实现]

FLUSH PRIVILEGES; #TODO

include/common/schema_factory.h Show resolved Hide resolved
src/common/schema_factory.cpp Show resolved Hide resolved
include/session/user_info.h Outdated Show resolved Hide resolved
@lgqss lgqss merged commit 0394fbd into baidu:master Apr 12, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants