MySQL 权限表在数据库启动时载入内存,用户通过身份认证后,系统会在内存中进行相应权限的存取。当 MySQL 允许一个用户执行各种操作时,它将首先核实该用户向 MySQL 服务器发送的连接请求,然后确认用户的操作请求是否被允许。
当用户进行连接时,MySQL 实现权限控制主要有以下两个阶段:
登录 MySQL 服务器时,客户端连接请求中会提供用户名称、主机地址和密码,MySQL 服务器会使用 user 表中的 Host、User 和 authentication_string (MySQL 5.7 版本之前是 Password)字段执行身份检查。
只有客户端请求的主机名和用户名在 user 表中有匹配的记录,并且密码正确时,MySQL 服务器才会通过身份认证,接受连接,否则拒绝连接。
MySQL 通过 IP 地址和用户名联合进行身份认证。例如 MySQL 安装后默认创建的用户 root@localhost,表示用户 root 只能从本地(localhost)进行连接时才能通过认证。此用户从其它任何主机对数据库进行连接时都将被拒绝。也就是说,用户名相同,IP 地址不同,MySQL 则将其视为不同的用户。
服务器接受连接后进入请求核实阶段等待用户请求。如果连接核实没有通过,服务器则完全拒绝访问。
建立连接后,服务器进入请求核实阶段,对在此连接上的每个请求,服务器都会检查用户是否有足够的权限来执行它。这正是授权表中的权限列发挥作用的地方。
权限按照以下权限表的顺序得到数据库权限:user→db→tables_priv→columns_priv→procs_priv。在这几个权限表中,权限范围依次递减,全局权限覆盖局部权限。
请求核实的过程如下所示:
1)用户向 MySQL 发出操作请求。
2)MySQL 首先检查 user 表,匹配 User、Host 字段值,查看请求的全局权限在 user 表中是否被授权。授权则允许操作执行,如果指定的权限在 user 表中没有被授权。MySQL 将检查 db 表。
3)db 表是下一安全层级,其中的权限限定于数据库层级,在该层级的 SELECT 权限允许用户查看指定数据库的所有表中的数据。
MySQL 检查 db 权限表中的权限信息,匹配 User、Host 字段值,查看请求的数据库级别的权限在 db 表中是否被授权。授权则允许操作执行,否则 MySQL 继续向下查找。
4)MySQL 检查 tables_priv 权限表中的权限信息,匹配 User、Host 字段值,查看请求的数据表级别的权限在 tables_priv 表中是否被授权。授权则允许操作执行,否则 MySQL 继续向下查找。
5)MySQL 检查 columns_priv 权限表中的权限信息,匹配 User、Host 字段值,查看请求的列级别的权限在 columns_priv 表中是否被授权。授权则允许操作执行,否则 MySQL 继续向下查找。
6)如果所有权限表都检查完毕,还是没有找到允许的权限操作,那么 MySQL 将返回错误信息,即用户请求的操作不能执行,操作失败。
提示:上面提到 MySQL 通过向下层级的顺序检查权限表,但并不意味着所有的权限都要执行该过程。例如,一个用户登录到 MySQL 服务器之后只执行对 MySQL 的管理操作,此时只涉及管理权限,因此 MySQL 只检查 user 表。