文档主页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  访问控制,阶段 2:请求验证

8.2.7 访问控制,阶段 2:请求验证

服务器接受连接后,将进入访问控制的阶段 2。对于您通过连接发出的每个请求,服务器都会确定您要执行的操作,然后检查您的权限是否足够。这就是授权表中的权限列发挥作用的地方。这些权限可以来自 userglobal_grantsdbtables_privcolumns_privprocs_priv 表中的任何一个。(您可能会发现参考第 8.2.3 节“授权表”会有所帮助,其中列出了每个授权表中存在的列。)

userglobal_grants 表授予全局权限。给定帐户的这些表中的行指示在全局范围内应用的帐户权限,而不管默认数据库是什么。例如,如果 user 表授予您 DELETE 权限,则您可以删除服务器主机上任何数据库中任何表中的行。明智的做法是,仅向需要 user 表中权限的人员(例如数据库管理员)授予权限。对于其他用户,请将 user 表中的所有权限设置为 'N',并仅在更具体的级别(对于特定数据库、表、列或例程)授予权限。也可以全局授予数据库权限,但使用部分撤销来限制它们在特定数据库上的执行(请参阅第 8.2.12 节“使用部分撤销限制权限”)。

db 表授予特定于数据库的权限。此表中范围列的值可以采用以下形式

  • 空白的 User 值与匿名用户匹配。非空白值按字面匹配;用户名中没有通配符。

  • 通配符 %_ 可用于 HostDb 列。它们的含义与使用 LIKE 运算符执行的模式匹配操作相同。如果要在授予权限时按字面使用任一字符,则必须使用反斜杠对其进行转义。例如,要将下划线字符 (_) 包含为数据库名称的一部分,请在 GRANT 语句中将其指定为 \_

  • '%' 或空白的 Host 值表示“任何主机。

  • '%' 或空白的 Db 值表示“任何数据库。

服务器在读取 user 表的同时,将 db 表读入内存并对其进行排序。服务器根据 HostDbUser 范围列对 db 表进行排序。与 user 表一样,排序时将最具体的值放在最前面,将最不具体的值放在最后面,并且当服务器查找匹配的行时,它使用找到的第一个匹配项。

tables_privcolumns_privprocs_priv 表授予特定于表、特定于列和特定于例程的权限。这些表中范围列的值可以采用以下形式

  • 通配符 %_ 可用于 Host 列。它们的含义与使用 LIKE 运算符执行的模式匹配操作相同。

  • '%' 或空白的 Host 值表示“任何主机。

  • DbTable_nameColumn_nameRoutine_name 列不能包含通配符或为空。

服务器根据 HostDbUser 列对 tables_privcolumns_privprocs_priv 表进行排序。这类似于 db 表排序,但更简单,因为只有 Host 列可以包含通配符。

服务器使用排序后的表来验证它收到的每个请求。对于需要管理权限的请求,例如 SHUTDOWNRELOAD,服务器仅检查 userglobal_privilege 表,因为这些表是唯一指定管理权限的表。如果这些表中帐户的行允许所请求的操作,则服务器授予访问权限,否则拒绝访问权限。例如,如果您要执行 mysqladmin shutdown,但您的 user 表行没有授予您 SHUTDOWN 权限,则服务器会拒绝访问,甚至不会检查 db 表。(后者表不包含 Shutdown_priv 列,因此无需检查。)

对于与数据库相关的请求(INSERTUPDATE 等),服务器首先检查 user 表行中的用户全局权限(减去部分撤销施加的任何权限限制)。如果该行允许所请求的操作,则授予访问权限。如果 user 表中的全局权限不足,则服务器从 db 表确定用户的数据库特定权限

  • 服务器在 db 表中查找 HostDbUser 列的匹配项。

  • HostUser 列与连接用户的 主机名和 MySQL 用户名匹配。

  • Db 列与用户想要访问的数据库匹配。

  • 如果没有 HostUser 的行,则拒绝访问。

在确定了 db 表行授予的数据库特定权限后,服务器会将它们添加到 user 表授予的全局权限中。如果结果允许所请求的操作,则授予访问权限。否则,服务器将依次检查 tables_privcolumns_priv 表中的用户表和列权限,将这些权限添加到用户的权限中,并根据结果允许或拒绝访问。对于存储例程操作,服务器使用 procs_priv 表而不是 tables_privcolumns_priv

用布尔术语表示,前面关于如何计算用户权限的描述可以概括如下

global privileges
OR database privileges
OR table privileges
OR column privileges
OR routine privileges

如果最初发现全局权限不足以执行所请求的操作,则服务器稍后将这些权限添加到数据库、表和列权限中,这可能并不明显。原因是请求可能需要多个类型的权限。例如,如果执行 INSERT INTO ... SELECT 语句,则需要 INSERTSELECT 权限。您的权限可能是 user 表行授予一个全局权限,而 db 表行专门为相关数据库授予另一个权限。在这种情况下,您拥有执行请求所需的权限,但服务器无法仅从您的全局权限或数据库权限中判断出来。它必须根据组合权限做出访问控制决策。