0 引言
MySQL是一个多用户数据库,具有功能强大的访问控制系统,可以为不同用户指定允许的权限。MySQL用户可以分为普通用户和root用户。root用户是超级管理员,拥有所有权限,包括创建用户、删除用户和修改用户的密码等管理权限;普通用户只拥有被授予的各种权限。用户管理包括管理用户账户、权限等。
1 权限表
MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在MySQL数据库中,由MySQL_install_db脚本初始化。存储账户权限信息的表主要有user、db、host、tables_priv、columns_priv和procs_priv。本节将为读者介绍这些表的内容和作用。
1.1 user表
user表是MySQL中最重要的一个权限表,记录允许连接到服务器的账号信息,里面的权限是全局级的。
1.1.1 用户列
user表的用户列包括Host、User、authentication_string,分别表示主机名、用户名和密码。其中User和Host为User表的联合主键。当用户与服务器之间建立连接时,输入的账户信息中的用户名称、主机名和密码必须匹配User表中对应的字段,只有3个值都匹配的时候,才允许连接的建立。这3个字段的值就是创建账户时保存的账户信息。修改用户密码时,实际就是修改user表的authentication_string字段的值。
1.1.2 权限列
权限列的字段决定了用户的权限,描述了在全局范围内允许对数据和数据库进行的操作。包括查询权限、修改权限等普通权限,还包括了关闭服务器、超级权限和加载用户等高级权限。普通权限用于操作数据库;高级权限用于数据库管理。user表中对应的权限是针对所有用户数据库的。这些字段值的类型为ENUM,可以取的值只能为Y和N,Y表示该用户有对应的权限;N表示用户没有对应的权限。查看user表的结构可以看到,这些字段的值默认都是N。如果要修改权限,可以使用GRANT语句或UPDATE语句更改user表的这些字段来修改用户对应的权限。
1.1.3 安全列
安全列只有6个字段,其中两个是ssl相关的,两个是x509相关的,另外两个是授权插件相关的。ssl用于加密;x509标准可用于标识用户;Plugin字段标识可以用于验证用户身份的插件,如果该字段为空,服务器使用内建授权验证机制验证用户身份。读者可以通过SHOW VARIABLES LIKE 'have_openssl'语句来查询服务器是否支持ssl功能。
1.1.4 资源控制列
资源控制列的字段用来限制用户使用的资源,包含4个字段,分别为:
(1)max_questions——用户每小时允许执行的查询操作次数。
(2)max_updates——用户每小时允许执行的更新操作次数。
(3)max_connections——用户每小时允许执行的连接操作次数。
(4)max_user_connections——用户允许同时建立的连接次数。
一个小时内用户查询或者连接数量超过资源控制限制,用户将被锁定,直到下一个小时,才可以在此执行对应的操作。可以使用GRANT语句更新这些字段的值。
1.2 db表
db表是MySQL数据中非常重要的权限表。db表中存储了用户对某个数据库的操作权限,决定用户能从哪个主机存取哪个数据库。
1.2.1 用户列
db表用户列有3个字段,分别是Host、User、Db,标识从某个主机连接某个用户对某个数据库的操作权限,这3个字段的组合构成了db表的主键。
1.2.2 权限列
db表中create_routine_priv和alter_routine_priv这两个字段表明用户是否有创建和修改存储过程的权限。
1.3 tables_priv表和columns_priv表
tables_priv表用来对表设置操作权限,columns_priv表用来对表的某一列设置权限。
tables_priv表
columns_priv表
tables_priv表有8个字段,分别是Host、Db、User、Table_name、Grantor、Timestamp、Table_priv和Column_priv,各个字段说明如下:(1)Host、Db、User和Table_name 4个字段分表示主机名、数据库名、用户名和表名。(2)Grantor表示修改该记录的用户。(3)Timestamp字段表示修改该记录的时间。(4)Table_priv表示对表的操作权限,包括Select、Insert、Update、Delete、Create、Drop、Grant、References、Index和Alter。(5)Column_priv字段表示对表中的列的操作权限,包括Select、Insert、Update和References。
columns_priv表只有7个字段,分别是Host、Db、User、Table_name、Column_name、Timestamp、Column_priv。其中,Column_name用来指定对哪些数据列具有操作权限。
1.4 procs_priv表
procs_priv表可以对存储过程和存储函数设置操作权限。
procs_priv表包含8个字段,分别是Host、Db、User、Routine_name、Routine_type、Grantor、Proc_priv和Timestamp,各个字段的说明如下:(1)Host、Db和User字段分别表示主机名、数据库名和用户名。Routine_name表示存储过程或函数的名称。(2)Routine_type表示存储过程或函数的类型。Routine_type字段有两个值,分别是FUNCTION和PROCEDURE:FUNCTION表示这是一个函数,PROCEDURE表示这是一个存储过程。(3)Grantor是插入或修改该记录的用户。(4)Proc_priv表示拥有的权限,包括Execute、Alter Routine、Grant 3种。(5)Timestamp表示记录更新时间。
2 账户管理
MySQL提供了许多语句来管理用户账号,包括登录和退出MySQL服务器、创建用户、删除用户、密码管理和权限管理等内容。MySQL数据库的安全性需要通过账户管理来保证。
2.1 登录和退出MySQL服务器
通过MySQL –help命令可以查看MySQL命令帮助信息。MySQL命令的常用参数如下:(1)-h主机名,可以使用该参数指定主机名或ip,如果不指定,默认是localhost。(2)-u用户名,可以使用该参数指定用户名。(3)-p密码,可以使用该参数指定登录密码。如果该参数后面有一段字段,则该段字符串将作为用户的密码直接登录。如果后面没有内容,则登录的时候会提示输入密码。注意:该参数后面的字符串和-p之前不能有空格。(4)-P端口号,该参数后面接MySQL服务器的端口号,默认为3306。(5)数据库名,可以在命令的最后指定数据库名。(6)-e执行SQL语句。如果指定了该参数,将在登录后执行-e后面的命令或SQL语句并退出。
退出MySQL服务器。在MySQL命令行界面中,可以使用quit或exit命令退出登录;
2.2 新建普通用户
使用CREATE USER语句来创建新用户。你可以指定用户名和该用户可以从哪些主机连接到MySQL服务器。
创建用户
CREATE USER '新用户名'@'主机名' IDENTIFIED BY '密码';
'新用户名' 是你想要创建的用户名。
'主机名' 是用户将用于连接到MySQL服务器的主机。如果你想允许该用户从任何主机连接,可以使用'%'。但是出于安全考虑,最好限制可以连接的主机。
'密码' 是用户的密码。确保选择一个强密码。
分配权限
如果你想给新用户对所有数据库的读权限
GRANT SELECT ON *.* TO '新用户名'@'%';
你只想给给新用户用户对特定数据库(例如mydatabase)的所有权限
GRANT ALL PRIVILEGES ON mydatabase.* TO '新用户名'@'%';
刷新权限
在分配了权限之后,需要执行FLUSH PRIVILEGES命令来使更改生效。
FLUSH PRIVILEGES;
请记住,出于安全考虑,你应该限制新用户的权限和允许连接的主机。不要授予不必要的权限,特别是SUPER、FILE、PROCESS等高风险权限。
2.3 删除普通用户
删除用户
使用DROP USER语句来删除用户。您需要指定要删除的用户的用户名和来源主机,要删除名为username的用户,该用户从任何主机连接,您可以使用以下命令:
DROP USER 'username'@'%';
如果要删除特定主机上的用户,您需要将%替换为具体的主机名或IP地址。例如,要删除仅从localhost连接的用户,您可以使用:
DROP USER 'username'@'localhost';
刷新权限
在分配了权限之后,需要执行FLUSH PRIVILEGES命令来使更改生效。
FLUSH PRIVILEGES;
请注意,执行这些命令需要具有足够的权限。如果您不是以管理员身份登录,可能无法删除用户。另外,在执行删除操作之前,请确保您不会意外删除重要的用户账户,因为这可能会影响数据库的安全性和可访问性。
2.4 root用户修改自己的密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
//root用户从任何主机连接,并修改其密码
ALTER USER 'root'@'%' IDENTIFIED BY 'new_password';
//修改密码后,为确保更改立即生效,您应该执行FLUSH PRIVILEGES命令:
FLUSH PRIVILEGES;
2.5 root用户修改普通用户密码
//MySQL 5.7或更高版本
ALTER USER 'username'@'localhost' IDENTIFIED BY 'new_password';
//刷新权限
FLUSH PRIVILEGES;
3 权限管理
权限管理主要是对登录到MySQL的用户进行权限验证。所有用户的权限都存储在MySQL的权限表中,不合理的权限规划会给MySQL服务器带来安全隐患。数据库管理员要对所有用户的权限进行合理规划管理。MySQL权限系统的主要功能是证实连接到一台给定主机的用户,并且赋予该用户在数据库上的SELECT、INSERT、UPDATE和DELETE权限。
权限
全局权限(Global Privileges):适用于整个MySQL服务器的权限,例如CREATE、DROP、RELOAD等。
数据库权限(Database Privileges):针对特定数据库的权限,例如CREATE、DROP、ALTER等。
表权限(Table Privileges):针对特定表的权限,例如SELECT、INSERT、UPDATE、DELETE等。
列权限(Column Privileges):针对特定表的列的权限,例如SELECT、INSERT、UPDATE等。
授予和撤销权限
GRANT:用于授予用户权限。
REVOKE:用于撤销用户的权限。
授予权限
-- 授予用户在特定数据库上的所有权限
GRANT ALL PRIVILEGES ON database_name.* TO 'username'@'host';
-- 授予用户在特定表上的SELECT和INSERT权限
GRANT SELECT, INSERT ON database_name.table_name TO 'username'@'host';
-- 授予用户全局权限,例如CREATE
GRANT CREATE ON *.* TO 'username'@'host';
//使用GRANT语句为特定用户授予对特定表中特定列的权限
GRANT SELECT, UPDATE (column1, column2, ...) ON database_name.table_name TO 'username'@'host';
//使用 GRANT 语句授予用户对特定存储过程的执行权限:
GRANT EXECUTE ON PROCEDURE procedure_name TO 'username'@'host';
撤销权限
-- 撤销用户在特定数据库上的所有权限
REVOKE ALL PRIVILEGES ON database_name.* FROM 'username'@'host';
-- 撤销用户在特定表上的SELECT和INSERT权限
REVOKE SELECT, INSERT ON database_name.table_name FROM 'username'@'host';
-- 撤销用户全局权限,例如CREATE
REVOKE CREATE ON *.* FROM 'username'@'host';
//使用REVOKE语句为特定用户撤销对特定表中特定列的权限
REVOKE SELECT, UPDATE (column1, column2, ...) ON database_name.table_name TO 'username'@'host';
//使用 REVOKE 语句撤销用户对特定存储过程的执行权限:
REVOKE EXECUTE ON PROCEDURE procedure_name TO 'username'@'host';
查看权限
SHOW GRANTS FOR 'username'@'host';
4 访问控制
正常情况下,并不希望每个用户都可以执行所有的数据库操作。当MySQL允许一个用户执行各种操作时,它将首先核实该用户向MySQL服务器发送的连接请求,然后确认用户的操作请求是否被允许。
MySQL的访问控制分为两个阶段:连接核实阶段和请求核实阶段。
4.1 连接核实阶段
当连接MySQL服务器时,服务器基于用户的身份以及用户是否能通过正确的密码身份验证来接受或拒绝连接,即客户端用户连接请求中会提供用户名称、主机地址名和密码。MySQL使用user表中的3个字段(Host、User和authentication_string)执行身份检查,服务器只有在user表记录的Host和User字段匹配客户端主机名和用户名并且提供正确的密码时才接受连接。如果连接核实没有通过,服务器完全拒绝访问;否则,服务器接受连接,然后进入阶段2等待用户请求。
4.2 请求核实阶段
建立了连接之后,服务器进入访问控制的阶段2。对在此连接上的每个请求,服务器检查用户要执行的操作,然后检查是否有足够的权限来执行它。这正是在授权表中的权限列发挥作用的地方。这些权限可以来自user、db、host、tables_priv或columns_priv表。
5 管理角色
在MySQL 8.0数据库中,角色可以看成是一些权限的集合,为用户赋予统一的角色,权限的修改直接通过角色来进行,无须为每个用户单独授权。
5.1 创建角色
使用CREATE ROLE语句来创建一个新的角色
CREATE ROLE 'dml_role';
5.2 给角色授权
GRANT SELECT, INSERT ON database_name.* TO 'dml_role';
5.3 将角色授予用户
GRANT 'dml_role' TO 'username'@'host';
5.4 查看角色权限
SHOW GRANTS FOR 'dml_role';
5.5 撤销角色权限
REVOKE INSERT ON database_name.* FROM 'dml_role';
5.6 删除角色
DROP ROLE 'dml_role';