访问控制
阶段一:连接验证
当客户端尝试连接到MySQL服务器时,服务器根据以下条件接受或拒绝连接:
提供的的身份凭据以及是否可以通过提供正确的密码来验证身份
账户是否已被锁定
服务器首先检查凭据,然后检查帐户锁定状态。任一步骤失败都会导致服务器完全拒绝您的访问。否则,服务器将接受连接,然后进入阶段二并等待请求。
凭据校验主要是通过校验user表中的user,host,authentication_string三个字段,账户锁定状态存储在user表中account_locked字段中。
使用三个用户表作用域列(主机,用户和认证字符串)执行凭据检查。锁定状态记录在用户表account_locked列中。仅当某些用户表行中的“主机”和“用户”列与客户端主机名和用户名匹配,客户端提供该行中指定的密码且account_locked值为“ N”时,服务器才接受连接。仅当某些用户表行中的user和host字段与客户端主机名和用户名匹配,客户端提供该行中指定的密码且account_locked值为N时,服务器才接受连接。
客户端身份基于以下两个信息:
客户端主机,即域名或IP地址
用户名,例如:root
如果user列的值是非空白的,则传入连接中的用户名必须完全匹配。如果user值为空白,则它与任何用户名匹配。如果与传入连接匹配的用户表行的用户名为空,则该用户将被视为没有名称的匿名用户,而不是具有客户端实际指定的名称的用户。这意味着在连接持续时间内(即在第2阶段),将使用空白用户名进行所有进一步的访问检查。
user表中的非空白authentication_string值表示加密的密码。MySQL不会将密码存储为明文,任何人都可以看到。而是将尝试连接的用户提供的密码进行加密(使用由帐户身份验证插件实现的密码哈希方法)。然后在检查密码是否正确时在连接过程中使用加密的密码。这样就不会在连接上传输加密密码。
mysql> select user, authentication_string from user where user = 'root' and host = '%';
+------+--------------------------------------------------------------------------------------------- ---------+
| user | authentication_string |
+------+-------------------------------------------------------------------------------------------------------+
| root | $A$005$%V,~wy({Nt{pt)1k?I,g6lMrrsej3UC5taF4V6/clkpGaYogHf7FIzwgijo3h9 |
+------+-------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
1
2
3
4
5
6
7
警告
从MySQL的角度来看,加密密码是真实密码,因此您绝不应该允许任何人访问它。特别是,请勿授予非管理用户对mysql系统数据库中表的读取权限。
下表显示了user表中user和host的各种组合如何应用于传入连接:
user
host
Permissible Connections
'fred'
'h1.example.net'
fred只能从h1.example.net连接到服务器
''
'h1.example.net'
任何用户都可以从 h1.example.net连接
'fred'
'%'
fred可以从任何主机连接到服务器
''
'%'
任何用户可以从任何主机连接到服务器
'fred'
'%.example.net'
fred可以从 example.net 域下任何主机连接
'fred'
'x.example.%'
fred可以从x.example.*域名连接
'fred'
'198.51.100.177'
fred只能从IP地址 198.51.100.177连接服务器
'fred'
'198.51.100.%'
fred可以从198.51.100.*网段连接
'fred'
'198.51.100.0/255.255.255.0'
等同于上一行
当客户端传入的身份凭据匹配多个条目时服务器必须确定要使用哪个匹配项。它可以按以下方式解决此问题:
每当服务器将用户表读入内存时,它都会对行进行排序。
客户端尝试连接时,服务器将按排序顺序浏览各行。
服务器使用与客户端主机名和用户名匹配的第一行。
服务器使用排序规则,该规则首先对具有最特定的主机值的行进行排序。主机名和IP地址是最具体的。(原义IP地址的特异性不受其是否具有网络掩码的影响,因此198.51.100.13和198.51.100.0/255.255.255.0被认为是同等具体的。)模式'%'表示“任何主机”,并且最少具体。空字符串""也表示“任何主机”,但在%之后排序。具有相同“主机”值的行将按照最特定的user值进行排序(空白的user值表示“任何用户”,并且是最不特定的)。对于具有相同特定的user和host值的行,顺序是不确定的。
要查看其工作原理,假设user表如下所示:
+---------------+----------+-
| Host | User | ...
+---------------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+------------ --+----------+-
1
2
3
4
5
6
7
8
当服务器将表读入内存时,它将使用刚刚描述的规则对行进行排序。排序后的结果如下所示:
当客户端尝试连接时,服务器将浏览已排序的行并使用找到的第一个匹配项。对于jeffrey与localhost的连接,表中的两行匹配:host和user值为'localhost'和''的那一行,以及host和user值为'%'和'jeffrey'的那一行。localhost行首先以排序顺序出现,因此服务器会使用这行。
这是另一个例子。假设用户表如下所示: