数据库:MySQL权限系统

了解MySQL的权限系统

权限表

通过网络连接服务器的客户对MySQL数据库的访问由权限表内容来控制。这些表位于mysql数据库中,并在第1次安装MySQL的过程中初始化。共有5个权限表:user、db、tables_priv、columns_priv和procs_priv。当MySQL服务启动时,首先读取MySQL中的权限表,并将表中的数据装入内存。当用户进行存取操作时,MySQL会根据这些表中的数据进行相应的权限控制。

权限表user和db的结构和作用

user表是MySQL中最重要的一个权限表,记录允许连接到服务器的账号信息。user表列出连接服务器的用户及其口令,并且指定他们有哪种全局(超级用户)权限。在user表启用的任何权限均是全局权限,并适用于所有数据库。MySQL 5.7中的user表有45个字段,共分为4类:

  • 用户列。user表的用户列包括Host、User,分别表示主机名、用户名。其中User和Host为User表的联合主键。当用户和服务器之间建立连接时,输入的账户信息中的用户名称、主机名必须匹配User表中对应的字段,只有两个值都匹配时,才会检测该表安全列中的authentication_string字段的值是否与用户输入的密码相匹配,只有三项都匹配,才允许建立连接。这3个字段的值在创建账户时保存的账户信息。修改用户密码时,实际是修改user表的authentication_string字段的值。

  • 权限列。user表的权限列包括Select_priv、Insert_priv等以priv结尾的字段。这些字段决定了用户的权限,描述了在全局范围内允许对数据和数据库进行的操作,包括查询权限、修改权限等普通权限,还包括关闭服务器、超级权限和加载用户等高级权限。普通权限用于操作数据库,高级权限用于管理数据库。这些字段的类型为ENUM,可以取的值只有Y和N,Y表示该权限可以用到所有数据库上,N表示用户没有该权限。从安全角度考虑,这些字段的默认值都为N。如果要修改权限,可以使用GRANT语句或UPDATE语句更改user表的相应字段值来修改用户对应的权限。

  • 安全列。安全列有10个字段,其中有两个与ssl相关,两个与x509有关,一个与授权插件相关,一个用于保存用户的密码,3个与用户的密码修改和有效期相关,还有一个与账户是否锁定有关。ssl用于加密,x509标准用于标识用户,plugin字段用于验证用户身份,authentication_string字段用于保存用户的密码,password_expired字段用于标识账号的密码过期时间,password_last_changed字段用于标识密码最近的修改时间,password_lifetime字段用于标识密码的有效时间,account_locked字段用于标识账号是否锁定。

  • 资源控制列。资源控制列的字段用来限制用户使用的资源。这些字段的默认值为0,表示没有限制。

db表也是MySQL数据库中非常重要的权限表。db表中存储了用户对某个数据库的操作权限,决定用户能从哪个主机存取哪个数据库。db权限表对给定主机上数据库级操作权限进行更细致的控制。字段大致可以分为两类:

  • 用户列。包括Host、User和Db,分别表示主机名、用户名和数据库名,标识从某个主机连接某个用户对某个数据库的操作权限,这3个字段的组合构成了db表的主键。

  • 权限列。user表的权限是针对所有数据库的,如果希望用户只对某个数据库有操作权限,那么需要将user表中对应的权限设置为N,然后在db表中设置对应数据的操作权限。用户先根据user表的内容获取权限,然后再根据db表的内容获取权限。

tables_priv表、columns_priv表和procs_priv表

tables_priv表用来对表设置操作权限,columns_priv表用来对表的某一列设置权限,procs_priv表可以对存储过程和存储函数设置操作权限。

  • Table_priv权限:Select、Insert、Update、Delete、Create、Drop、Grant、References、Index、Alter等。

  • Column_priv权限:Select、Insert、Update和References等。

  • Routine_type字段有两个值,分别是FUNCTION和PROCEDURE。FUNCTION表示是一个函数,PROCEDURE表示是一个存储过程。Proc_priv权限包括Execute、Alter Routine和Grant3种。

MySQL权限系统的工作原理

为了确保数据库的安全性与完整性,系统并不希望每个用户都可以执行所有的数据库操作。当MySQL允许一个用户执行各种操作时,它将首先核实用户向MySQL服务器发送的连接请求,然后确保用户的操作请求是否被允许。MySQL的访问控制分为两个阶段:连接核实阶段和请求核实阶段。

连接核实阶段

当用户试图连接MySQL服务器时,服务器基于用户提供的信息来验证用户身份,如果不能通过身份验证,服务器就完全拒绝该用户的访问。如果能够通过身份验证,则服务器接受连接,然后进入第2个阶段等待用户请求。MySQL使用user表中的3个字段(Host、User和authentication_string)检测身份,服务器只有在用户提供主机名、用户名和密码并与user表中对应的字段值完全匹配时才接受连接。User表中的非空authentication_string值是经过加密的用户密码。MySQL不以任何人均可见的纯文本格式存储密码,相反,正在试图连接的一个用户提供的密码被加密(使用PASSWORD()函数),并且与存储在user表中的已经加密的版本比较。如果它们匹配,那么说明密码是正确的。

请求核实阶段

一旦连接得到许可,服务器便进入请求核实阶段。在这一阶段,MySQL服务器对当前用户的每个操作都进行权限检查,判断用户是否有足够的权限来执行它。用户的权限保存在user、db、tables_priv或columns_priv权限表中。在MySQL权限表的结构中,user表在最顶层,是全局级的。下面是db表,这两个表是数据库层级的。最后才是tables_priv表和columns_priv表,它们是表级和列级的。低等级的表只能是从高等级得到必要的范围或权限。

确认权限时,MySQL首先检查user表,如果指定的权限没有在user表中被授权,则MySQL服务器检查db表,在该层级的SELECT权限允许用户查看指定数据库的所有表的数据。如果在该层级没有找到限定的权限,则MySQL继续检查tables_priv表以及columns_priv表。如果所有权限表都检查完毕,依旧没有找到允许的权限操作,则MySQL服务器将返回错误信息,用户操作不能执行,操作失败。

MySQL通过向下层级的顺序检查权限表(从user表到columns_priv表),并不是所有的权限都要执行该过程。例如,一个用户登录到MySQL服务器后,只执行对MySQL的管理操作,此时只涉及管理操作,MySQL将只检查user表。另外,如果请求的权限不被允许,MySQL就不会继续检查下一层级的表。

管理数据库用户权限

用户管理

MySQL的账户管理包括登录和退出MySQL服务器、创建用户、删除用户、密码管理和权限管理等内容。通过账户管理,可以保证MySQL数据库的安全性。

# 创建新用户
CREATE USER user [IDENTIFIED BY [PASSWORD]'password'] [,user [IDENTIFIED BY [PASSWORD]'password']] [,...];
或
GRANT priv_type ON database.table TO user [IDENTIFIED BY [PASSWORD]'password'] [WITH GRANT OPTION];
或
INSERT INTO mysql.user (HOST,User,authentication_string,ssl_cipher,x509_issuer,x509_subject) 
    VALUES('hostname','username',PASSWORD('authentication_string'),'','','');
FLUSH PRIVILEGES;   # 使用户生效

# 删除用户
DROP USER user_name[,user_name] [,...];
或
DELETE FROM mysql.user WHERE host='hostname' and user='username';

# 修改用户名称
RENAME USER old_user TO new_user [,old_user TO new_user] [,...];

# 修改密码
mysqladmin -u username -h localhost -p password 'newpassword';    # 命令行
或
UPDATE mysql.user set authentication_string=PASSWORD('newpassword') WHERE user='root' and host='localhost';
FLUSH PRICILEGES;     # 重新加载用户权限表
与
SET PASSWORD [FOR user]= PASSWORD('newpassword');

如果删除的用户已经创建了表、索引或其他的数据库对象,它们将继续保留,因为MySQL并没有记录是谁创建了这些对象。

user的值必须以'user_name'@'host_name'的格式给定。

权限管理

权限管理主要是对登录到MySQL的用户进行权限验证。所有用户的权限都存储在MySQL的权限表中。在MySQL启动时,服务器将MySQL数据库中的权限信息读入内存。

# 授权
GRANT priv_type [(column_list)] [,priv_type [(column_list)]] [,...]
    ON {table_name|*|*.*|database_name.*|database_name.table_name}
    TO user[IDENTIFIED BY [PASSWORD]'password'] [,user[IDENTIFIED BY [PASSWORD]'password']] [,...]
    [WITH GRANT OPTION];
WITH GRANT OPTIIN:
    GRANT OPTION、MAX_QUERIES_PER_HOUR count、MAX_UPDATES_PER_HOUR count、
    MAX_CONNECTIONS_PER_HOUR count、MAX_USER_PER_HOUR count

# 收回权限
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'username'@'hostname' [,'username'@'hostname'] [,...];
或
REVOKE priv_type [(column_list)] [,priv_type [(column_list)]] [,...]
    ON {table_name|*|*.*|database_name.*|database_name.table_name}
    FROM 'username'@'hostname' [,'username'@'hostname'] [,...];

# 查看权限
SHOW GRANTS FOR 'username'@'hostname';

(最近更新:2019年09月03日)

你可能感兴趣的:(Interview)