13.1 访问权限控制系统概述
什么是访问权限控制系统?
MySQL的mysql系统库提供了user、db、tables_priv、columns_priv、procs_priv、proxies_priv几个表,用于存放不同权限范围的用户账号相关数据,这些表共同组成了MySQL的访问权限控制系统。
MySQL访问权限控制系统的主要功能是对从给定主机连接到MySQL服务器的用户进行身份验证,并校验该用户在该服务器中的数据库对象访问权限(如SELECT、INSERT、UPDATE和DELETE)。另外,还包括管理匿名用户访问和授予特定的MySQL权限的功能(如执行LOAD DATA INFILE语句和管理操作权限等)。
MySQL访问权限控制系统的用户界面由几条SQL语句组成,如CREATE USER、GRANT和REVOKE。
在服务器内部,MySQL将权限信息存储在mysql系统库的权限表中。MySQL服务器在启动时将这些表的内容读入内存,后续针对用户的访问控制决策基于权限表的内存副本来实现。
MySQL访问权限控制系统可以确保只有被允许的(与用户权限匹配的)操作才能够在服务器中执行。当一个用户连接到MySQL服务器时,其认证身份由“请求连接的主机名和用户名”确定,MySQL使用主机名+用户名的方式来识别和区分“相同主机不同用户”和“不同主机相同用户”发出的请求(例如:从office.example.com连接的用户joe和从home.example.com连接的用户joe在MySQL服务器中实际上是被当作两个不同的连接者来处理的,所以可以设置不同的密码、不同的权限)。例如:
mysql> show grants for test_a@'localhost'; +---------------------------------------------+ | Grants for test_a@localhost | +---------------------------------------------+ | GRANT SELECT ON *.* TO 'test_a'@'localhost' | +---------------------------------------------+ 1 row in set(0.00 sec) mysql> show grants for test_a@'%'; +---------------------------------------------+ | Grants for test_a@% | +---------------------------------------------+ | GRANT SELECT, INSERT ON *.* TO 'test_a'@'%' | +---------------------------------------------+ 1 row in set(0.00 sec)
当用户使用客户端程序连接到MySQL服务器时,MySQL的访问控制分为如下两个阶段。
● 阶段1:服务器根据身份标识(主机名+用户名组成的账号名称)在MySQL的访问权限控制表中查询相关信息,以确定需要接受或拒绝该用户的连接(没有查询到就拒绝连接)。如果查询到了用户记录,则校验用户提供的账号密码是否正确,如果密码不正确则拒绝连接。这个阶段的报错信息类似于:ERROR 1045(28000): Access denied for user 'test_a'@'localhost'(using password: YES)。
● 阶段2:用户连接成功之后,服务器会检查用户访问请求中的每个声明,确定是否有足够的权限来执行。例如:如果尝试从数据库的表中查询数据行或从数据库中删除表,服务器将验证该用户否具有该表的SELECT权限或数据库的DROP权限,如果无对应权限,则这个阶段的报错信息类似于:ERROR 1142(42000)at line 1:UPDATE command denied to user 'test_a'@'localhost' for table 'sbtest1'。
如果某用户在连接期间发生了权限变更(自己或者其他用户修改了权限),那么该用户执行下一条语句时,该权限变更不一定会立即生效。如果未生效,则需要执行FLUSH PRIVILEGES;语句。