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

构建连接后,服务器进入访问控制的第二阶段。对于通过该连接发出的每个请求,服务器都会确定要执行的操作,然后检查您是否具有足够的特权。这是授予 table 中的特权列起作用的地方。这些特权可以来自userdbtables_privcolumns_privprocs_privtable 中的任何一个。 (您可能会发现参考第 6.2.3 节“授权 table”很有帮助,该列 table 列出了每个授权 table 中存在的列。)

usertable 授予全局特权。帐户的usertable 行指示无论默认数据库是什么,在全局基础上应用的帐户特权。例如,如果usertable 授予您DELETE特权,则可以从服务器主机上任何数据库中的任何 table 中删除行。明智的是,仅将usertable 中的特权授予需要它们的人,例如数据库 Management 员。对于其他用户,请将usertable 中的所有特权设置为'N'并仅在更特定的级别(对于特定的数据库,table,列或例程)授予特权。

dbtable 授予特定于数据库的特权。该 table 的范围列中的值可以采用以下形式:

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

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

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

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

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

tables_privcolumns_privprocs_privtable 授予 table 特定,列特定和例程特定的特权。这些 table 的作用域列中的值可以采用以下形式:

  • 通配符%_可以在Host列中使用。这些含义与使用LIKE运算符执行的模式匹配操作相同。

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

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

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

服务器使用排序的 table 来验证它收到的每个请求。对于要求 Management 特权(例如SHUTDOWNRELOAD)的请求,服务器仅检查usertable 行,因为这是唯一指定 Management 特权的 table。如果该行允许请求的操作,则服务器将授予访问权限,否则将拒绝访问。例如,如果您要执行mysqladmin shutdown,但是usertable 行未授予您SHUTDOWN特权,则服务器将拒绝访问,甚至不检查dbtable。 (后一个 table 不包含Shutdown_priv列,因此无需检查它.)

对于与数据库相关的请求(INSERTUPDATE等),服务器首先在usertable 行中检查用户的全局特权。如果该行允许请求的操作,则授予访问权限。如果usertable 中的全局特权不足,则服务器从dbtable 中确定用户的数据库特定特权:

服务器在dbtable 中查找HostDbUser列上的匹配项。 HostUser列与连接用户的主机名和 MySQL 用户名匹配。 Db列与用户要访问的数据库匹配。如果HostUser没有行,则拒绝访问。

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

用布尔值 table 示,前面关于如何计算用户特权的描述可以总结如下:

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges
OR routine privileges

可能不清楚,为什么,如果最初发现全局特权不足以执行请求的操作,则服务器随后会将这些特权添加到数据库,table 和列特权中。原因是请求可能需要一种以上的特权。例如,如果执行插入...选择语句,则需要INSERTSELECT特权。您的特权可能是usertable 行授予一个全局特权,而dbtable 行授予另一个特权,专门针对相关数据库。在这种情况下,您具有执行请求所必需的特权,但是服务器无法仅从全局特权或数据库特权中分辨出这一点。它必须根据组合的权限做出访问控制决定。