-
MYSQL 8.0之访问控制(2)
h1.example.net
的jeffrey
连接,第二行匹配来自任何主机的jeffrey
连接。
提示
常见的误解是认为,当客户端从某个主机以用户名密码登录时服务器会完全匹配其信息,这是不对的。前面的示例对此进行了说明,其中
jeffrey
与h1.example.net
的连接首先不匹配包含jeffrey
作为user
字段值的行,而是不匹配用户名的行。结果,即使jeffrey
在连接时指定了用户名,他仍被认证为匿名用户。
如果您能够连接到服务器,但是特权不是您所期望的,则您可能已通过其他帐户的身份验证。要找出服务器用来验证您身份的帐户,请使用CURRENT_USER()
函数。此函数会返回user_name@host_name
格式返回一个值,该值指示匹配的用户表行中的user
和host
值。
阶段二:请求验证
建立连接后,服务器进入访问控制的第二阶段。对于通过该连接发出的每个请求,服务器将确定要执行的操作,然后检查是否具有足够的特权。这是授权表中的特权列起作用的地方。这些特权可以来自任何用户,global_grants
,db
,tables_priv
,columns_priv
或procs_priv
表。
user
和global_grants
表授予全局特权。这些表中给定帐户的行表示无论默认数据库是什么,在全局基础上应用的帐户特权。例如,如果用户表授予您DELETE
特权,则可以从服务器主机上任何数据库中的任何表中删除行。明智的做法是仅将需要特权的用户授予用户表中的特权,例如数据库管理员。对于其他用户,请将用户表中的所有特权都设置为N
,并仅在更特定的级别(对于特定的数据库,表,列或例程)授予特权。也可以全局授予数据库特权,但可以撤销部分权限来限制它们在特定数据库上的执行。 db
表授予特定于数据库的特权。该表的scope
列中的值可以采用以下形式:
- 空的用户值与匿名用户匹配。非空值从字面上匹配;用户名中没有通配符。
-
通配符
%
和可以在host
和db
列中使用。这些具有与使用LIKE
运算符执行的模式匹配操作相同的含义。如果要在授予特权时按字面使用任何一个字符,则必须使用反斜杠将其转义。例如,要将下划线字符(_)包括在数据库名称中,请在GRANT
语句中将其指定为\_
。 -
%
或空白host
值表示“任何主机”。 -
%
或空白db
值表示“任何数据库”。
服务器将数据库表读入内存,并在读取user
表的同时对其进行排序。服务器根据host
,db
和user
列对数据库表进行排序。与用户表一样,排序将最具体的值放在最前面,最不具体的值放在最后,当服务器寻找匹配的行时,它将使用找到的第一个匹配项。 服务器使用排序的表来验证它收到的每个请求。对于需要管理特权(例如SHUTDOWN
或RELOAD
)的请求,服务器仅检查user
和global_privilege
表,因为它们是唯一指定管理特权的表。如果这些表中帐户的行允许请求的操作,则服务器将授予访问权限,否则拒绝访问。例如,如果您想执行mysqladmin shutdown
,但是您的用户表行未授予您SHUTDOWN
特权,则服务器将拒绝访问,甚至不检查db
表。(后一个表不包含Shutdown_priv
列,因此无需检查它。)
对于与数据库相关的请求(INSERT
,UPDATE
等),服务器首先在user
表行中检查用户的全局特权(减去部分撤销所施加的任何特权限制)。如果该行允许请求的操作,则授予访问权限。如果用户表中的全局特权不足,则服务器从数据库表中确定用户的数据库特定特权:
服务器在db
表中查找host
,db
和user
列上的匹配项。host
和user
列与连接用户的主机名和MySQL用户名匹配。db
列与用户要访问的数据库匹配。如果主机和用户没有行,则拒绝访问。 在确定db
表行授予的特定于数据库的特权之后,服务器会将它们添加到user
表授予的全局特权中。如果结果允许请求的操作,则授予访问权限。否则,服务器会先检查tables_priv和columns_priv
表中用户的表特权和列特权,将这些特权添加到用户特权中,然后根据结果允许或拒绝访问。对于存储过程操作,服务器使用procs_priv
表而不是table_priv
和columns_priv
。
前面关于如何计算用户特权的描述可以总结如下:
- 1
- 2
- 3
- 4
- 5
上面介绍的请求权限验证流程可能令人迷惑,如果最初发现全局特权不足以执行请求的操作,则服务器随后会将这些特权添加到数据库,表和列特权中。原因是请求可能需要一种以上的特权。例如,如果执行INSERT INTO ... SELECT
语句,则需要INSERT
和SELECT
特权。您的特权可能是这样的:user
表行授予一个全局特权,而数据库表行授予另一个特权,专门针对相关数据库。在这种情况下,您具有执行请求所必需的特权,但是服务器无法仅从全局特权或数据库特权中分辨出这一点。它必须根据组合的权限做出访问控制决定。