MySQL将帐户存储在系统数据库的user表中 mysql。根据用户名和用户可以从其连接到服务器的客户端主机或主机来定义帐户
该帐户也可能有一个密码。MySQL支持身份验证插件,因此帐户可能会使用一些外部身份验证方法进行身份验证
MySQL用户名长达32个字符(MySQL 5.7.8之前为16个字符)。操作系统用户名可能具有不同的最大长度
要验证使用MySQL本地身份验证的帐户(由mysql_native_password验证插件实施)的客户端连接 ,服务器将使用存储在user表中的密码 。这些密码与登录到操作系统的密码不同。 用于登录到Windows或Unix机器的“ 外部 ”密码与用于访问该机器上的MySQL服务器的密码之间没有必要的连接
要使用命令行客户端连接到MySQL服务器,请根据需要为要使用的帐户指定用户名和密码选项:
shell> mysql --user=finley --password db_name
如果您喜欢短选项,命令如下所示:
shell> mysql -u finley -p db_name
如果您忽略 命令行上的--password或-p选项后面的密码值(如刚才所示),客户端会提示输入密码 。或者,可以在命令行中指定密码:
shell> mysql --user=finley --password=password db_name
shell> mysql -u finley -ppassword db_name
如果使用该-p选项,则密码值之间必须有 空格-p。
在命令行上指定密码应该被认为是不安全的
您可以通过两种方法创建MySQL帐户:
-
通过使用用于创建帐户并建立其权限的帐户管理语句,例如
CREATE USER
和GRANT
。这些语句导致服务器对底层授权表进行适当的修改。
首选方法是使用帐户管理语句,因为它们比直接操作授权表更简洁,更容易出错。所有这些声明在第13.7.1节“客户管理声明”中有描述。不鼓励直接授权表的操作,这里不再赘述。服务器可以自由地忽略由于这种修改而导致格式错误的行。
创建帐户的另一个选择是使用GUI工具MySQL Workbench。另外,几个第三方程序提供MySQL帐户管理功能。phpMyAdmin
是一个这样的程序。
以下示例显示如何使用 mysql客户端程序来设置新帐户。这些示例假设已根据第2.10.4节“保护初始MySQL帐户”中描述的默认设置了权限。这意味着要进行更改,您必须以MySQL root
用户身份连接到MySQL服务器,该用户具有 CREATE USER
权限。
首先,使用mysql程序作为MySQL root
用户连接到服务器:
shell> mysql --user=root mysql
如果您已经为该root
帐户指定了密码,那么您还必须提供一个--password
或 -p
选项。
连接到服务器后root
,您可以添加新帐户。以下示例使用 CREATE USER
和 GRANT
语句来设置四个帐户:
mysql> CREATE USER 'finley'@'localhost' IDENTIFIED BY 'some_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'finley'@'localhost'
-> WITH GRANT OPTION;
mysql> CREATE USER 'finley'@'%' IDENTIFIED BY 'some_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'finley'@'%'
-> WITH GRANT OPTION;
mysql> CREATE USER 'admin'@'localhost' IDENTIFIED BY 'admin_pass';
mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';
mysql> CREATE USER 'dummy'@'localhost';
由这些语句创建的帐户具有以下属性:
-
两个帐户的用户名
finley
和密码为some_pass
。两者都是具有完全权限的超级用户帐户。该'finley'@'localhost'
帐户只能在从本地主机连接时使用。该'finley'@'%'
帐户使用'%'
通配符作为主机部分,因此可用于从任何主机连接。'finley'@'localhost'
如果有匿名用户帐户, 该帐户是必需的localhost
。没有'finley'@'localhost'
帐户,当finley
从本地主机连接并且finley
被视为匿名用户时,该匿名用户帐户优先 。这样做的原因是匿名用户帐户具有Host
比'finley'@'%'
帐户更具体的列值 ,因此在user
表排序顺序中更早。(user
表排序在 6.2.4节“访问控制,阶段1:连接验证”中讨论。) -
该
'admin'@'localhost'
帐户的密码为admin_pass
。该帐户只能由admin
本地主机连接使用。它被授予RELOAD
和PROCESS
管理权限。这些权限允许admin
用户执行 中mysqladmin重装,中mysqladmin刷新和中mysqladmin潮红xxx
命令,以及中mysqladmin的processlist。没有权限访问任何数据库。您可以使用GRANT
语句添加此类权限。 -
该
'dummy'@'localhost'
帐户没有密码(这是不安全的,不推荐)。此帐户只能用于从本地主机连接。没有授予特权。假设您将使用GRANT
语句向帐户授予特定权限 。
要查看帐户的权限,请使用 SHOW GRANTS
:
mysql> SHOW GRANTS FOR 'admin'@'localhost';
+-----------------------------------------------------+
| Grants for admin@localhost |
+-----------------------------------------------------+
| GRANT RELOAD, PROCESS ON *.* TO 'admin'@'localhost' |
+-----------------------------------------------------+
要查看帐户的非特权属性,请使用 SHOW CREATE USER
:
mysql> SHOW CREATE USER 'admin'@'localhost'\G
*************************** 1. row ***************************
CREATE USER for admin@localhost: CREATE USER 'admin'@'localhost'
IDENTIFIED WITH 'mysql_native_password'
AS '*67ACDEBDAB923990001F0FFB017EB8ED41861105'
REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK
下一个示例创建三个帐户并授予他们对特定数据库的访问权限。他们每个用户名 custom
和密码为 obscure
:
mysql> CREATE USER 'custom'@'localhost' IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON bankaccount.*
-> TO 'custom'@'localhost';
mysql> CREATE USER 'custom'@'host47.example.com' IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON expenses.*
-> TO 'custom'@'host47.example.com';
mysql> CREATE USER 'custom'@'%.example.com' IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON customer.*
-> TO 'custom'@'%.example.com';
三个帐户可以使用如下:
-
第一个帐户可以访问
bankaccount
数据库,但只能从本地主机访问。 -
第二个帐户可以访问
expenses
数据库,但只能从主机访问host47.example.com
。 -
第三个帐户可以
customer
从example.com
域中的任何主机访问数据库。由于使用%
帐户名称的主机部分中的通配符,该帐户可以访问域中的所有计算机。
要删除帐户,请使用第13.7.1.3节“DROP用户语法”中DROP USER
描述的语句 。例如:
mysql> DROP USER 'jeffrey'@'localhost';
MySQL安装过程的一部分是数据目录初始化(参见 第2.10.1.1节“使用mysqld手动初始化数据目录”)。在数据目录初始化期间,MySQL创建应被视为保留的用户帐户:
-
'root'@'localhost
:用于行政管理。此帐户具有所有权限,可以执行任何操作。严格来说,这个帐号名称并不是保留的,因为某些安装将
root
帐户重命名 为别的东西,以避免用一个着名的名字暴露一个高度特权的帐户。 -
'mysql.sys'@'localhost'
:作为DEFINER
对sys
架构对象。使用该mysql.sys
帐户可避免DBA重命名或删除该root
帐户时出现的问题。该帐户被锁定,因此不能用于客户端。 -
'mysql.session'@'localhost'
:内部使用插件访问服务器。该帐户被锁定,因此不能用于客户端
限制客户端使用MySQL服务器资源的一种方法是将全局 max_user_connections
系统变量设置为非零值。这限制了任何给定帐户可以进行的同时连接的数量,但不会限制客户端在连接后可以执行的操作。另外,设置 max_user_connections
不能管理个人帐户。这两种类型的控制都是MySQL管理员感兴趣的。
为了解决这些问题,MySQL允许在使用这些服务器资源时对个别帐户进行限制:
-
帐户可以每小时发出的查询数量
-
帐户每小时可更新的次数
-
帐户可以每小时连接到服务器的次数
-
由帐户同时连接到服务器的数量
任何客户端可以发出的声明违反查询限制,除非其结果从查询缓存中提供。只有修改数据库或表的语句才会计入更新限制。
要在帐户创建时为帐户建立资源限制,请使用该CREATE USER
语句。要修改现有帐户的限制,请使用 ALTER USER
。(在MySQL 5.7.6之前GRANT
,用于新帐户或现有帐户。)提供一个WITH
命名每个要限制的资源的子句。每个限制的默认值为零(无限制)。例如,要创建一个可以访问customer
数据库但仅限于有限的新帐户,请发出以下语句:
mysql> CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank'
-> WITH MAX_QUERIES_PER_HOUR 20
-> MAX_UPDATES_PER_HOUR 10
-> MAX_CONNECTIONS_PER_HOUR 5
-> MAX_USER_CONNECTIONS 2;
限制类型不必全部在 WITH
子句中命名,而是可以以任何顺序存在。每个小时限制的值应该是表示每小时计数的整数。因为MAX_USER_CONNECTIONS
,limit是表示该帐户同时连接的最大数量的整数。如果此限制设置为零,则全局 max_user_connections
系统变量值确定同时连接的数量。如果max_user_connections
也为零,则帐户没有限制。
要修改现有帐户的限制,请使用 ALTER USER
语句。以下语句将查询限制更改为francis
100:
mysql> ALTER USER 'francis'@'localhost' WITH MAX_QUERIES_PER_HOUR 100;
该声明仅修改指定的限制值,并保留该帐户的其他方式不变。
要删除限制,请将其值设置为零。例如,要删除每小时francis
连接多少次的限制,请使用以下语句:
mysql> ALTER USER 'francis'@'localhost' WITH MAX_CONNECTIONS_PER_HOUR 0;
如前所述,帐户的同时连接限制是从 MAX_USER_CONNECTIONS
限制和 max_user_connections
系统变量确定的。假设全局max_user_connections
值为10,并且三个帐户具有如下规定的个别资源限制:
ALTER USER 'user1'@'localhost' WITH MAX_USER_CONNECTIONS 0;
ALTER USER 'user2'@'localhost' WITH MAX_USER_CONNECTIONS 5;
ALTER USER 'user3'@'localhost' WITH MAX_USER_CONNECTIONS 20;
user1
连接限制为10(全局 max_user_connections
值),因为它的MAX_USER_CONNECTIONS
极限为零。user2
并且分别user3
具有5和20的连接限制,因为它们具有非零MAX_USER_CONNECTIONS
限制。
服务器将帐户的资源限制存储在user
与该帐户对应的 表行中。the max_questions
, max_updates
and max_connections
列存储每小时限制,max_user_connections
列存储MAX_USER_CONNECTIONS
限制。(见 第6.2.2节“授予表”。)
资源使用计数发生在任何帐户对其使用任何资源的非零限制时。
随着服务器的运行,它计算每个帐户使用资源的次数。如果一个帐户在最近一个小时内达到了连接数量的限制,服务器会拒绝该帐户的进一步连接,直到该小时结束。类似地,如果帐户达到对查询或更新数量的限制,则服务器拒绝进一步的查询或更新,直到小时结束。在所有这些情况下,服务器发出适当的错误消息。
资源计数发生在每个帐户,而不是每个客户端。例如,如果您的帐户的查询限制为50,则通过与服务器进行两个同时的客户端连接,您不能将您的限制增加到100。在两个连接上发出的查询都在一起计算。
目前每小时的资源使用计数可以针对所有帐户全部重置,也可以单独针对给定的帐户重置:
-
要将所有帐户的当前计数重置为零,请发出
FLUSH USER_RESOURCES
声明。还可以通过重新加载授予表来重置计数(例如,使用FLUSH PRIVILEGES
语句或mysqladmin reload命令)。 -
通过再次设置其任何限制,个人帐户的计数可以重置为零。指定等于当前分配给该帐户的值的限制值。
每小时计数器复位不影响 MAX_USER_CONNECTIONS
限制。
当服务器启动时,所有计数从零开始。计数不会通过服务器重新启动进行。
对于MAX_USER_CONNECTIONS
限制,如果帐户当前已打开允许的最大连接数,则可能会发生边缘情况:连接之后快速断开可能会导致错误(ER_TOO_MANY_USER_CONNECTIONS
或 ER_USER_LIMIT_REACHED
)如果服务器尚未完全处理断开连接时间连接发生。当服务器完成断开连接处理时,再次允许连接。
连接到MySQL服务器的客户端的必需凭据可以包含密码。本节介绍如何为MySQL帐户分配密码。
MySQL将密码存储在系统数据库的user
表中 mysql
。分配或修改密码的操作仅允许具有该CREATE USER
权限的用户 ,或者替换为mysql
数据库的INSERT
权限(创建新帐户的UPDATE
权限,修改现有帐户的权限)。如果read_only
启用了 系统变量,则使用帐户修改语句(例如CREATE USER
或 SET PASSWORD
另外需要该SUPER
权限)。
MySQL哈希存储在mysql.user
表中的密码混淆它们。对于这里描述的大多数语句,MySQL自动哈希指定的密码。一个例外是 ,您 明确使用该函数来哈希密码。也有语法为, , ,和按字面指定许可证散列值; 有关详细信息,请参阅这些声明的说明。 SET PASSWORD ... = PASSWORD('
auth_string
')PASSWORD()
CREATE USER
ALTER USER
GRANT
SET PASSWORD
MySQL使用插件来执行客户端认证; 请参见 第6.3.9节“可插拔认证”。与帐户关联的身份验证插件确定用于为该帐户填写密码的算法。
要在创建新帐户时分配密码,请使用 CREATE USER
并包含 IDENTIFIED BY
子句:
mysql> CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
对于这种CREATE USER
语法,MySQL会在将密码存储在mysql.user
表中之前自动进行哈希 。
CREATE USER
还支持用于指定帐户验证插件的语法。请参见 第13.7.1.2节“创建用户语法”。
要为现有帐户分配或更改密码,请使用以下方法之一:
-
使用
ALTER USER
带有IDENTIFIED BY
子句的语句:mysql> ALTER USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
如果您没有以匿名用户身份连接,您可以更改自己的密码,而不用直接命名自己的帐户:
mysql> ALTER USER USER() IDENTIFIED BY 'mypass';
对于这些
ALTER USER
语法,MySQL在将其存储在mysql.user
表中之前自动将其密码化。ALTER USER
从MySQL 5.7.6开始,更改密码的语法是可用的。 -
使用
SET PASSWORD
与PASSWORD()
功能:mysql> SET PASSWORD FOR 'jeffrey'@'localhost' = PASSWORD('mypass');
如果您没有作为匿名用户连接,您可以通过省略
FOR
条款来更改自己的密码:mysql> SET PASSWORD = PASSWORD('mypass');
该
PASSWORD()
功能使用由old_passwords
系统变量值的值确定的散列方法对密码进行散列。如果SET PASSWORD
拒绝返回的散列密码值为PASSWORD()
不正确的格式,则可能需要更改old_passwords
以更改哈希方法。请参见第13.7.1.7节“设置密码语法”。注意从MySQL 5.7.6开始,不再 使用密码修改功能。使用来代替。
SET PASSWORD ... = PASSWORD('
auth_string
')ALTER USER
-
使用
SET PASSWORD
无PASSWORD()
功能:对于此语法,MySQL 5.7.6及更早版本中的含义不同:
-
从MySQL 5.7.6开始,
SET PASSWORD
将该字符串解释为明文字符串,并将其存储在mysql.user
帐户行中,对帐户认证插件进行适当的散列 。mysql> SET PASSWORD FOR -> 'jeffrey'@'localhost' = 'mypass';
-
在MySQL 5.7.6之前,
SET PASSWORD
将该字符串解释为要直接存储的散列密码值。mysql> SET PASSWORD FOR -> 'jeffrey'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';
字符串必须以帐户验证插件所需的格式进行散列。未正确散列的字符串导致帐户的客户端连接失败并出现
Access denied
错误。
-
-
使用
GRANT USAGE
全局(ON *.*
)级别的语句来更改帐户密码,而不影响帐户的当前权限:mysql> GRANT USAGE ON *.* TO 'jeffrey'@'localhost' -> IDENTIFIED BY 'mypass';
对于这种
GRANT
语法,MySQL会在将密码存储在mysql.user
表中之前自动进行哈希 。注意GRANT
从MySQL 5.7.6开始,不再 使用密码修改功能。使用ALTER USER
来代替。 -
要从命令行更改帐户密码,请使用 mysqladmin命令:
shell> mysqladmin -u user_name -h host_name password "new_password"
针对该命令设置密码的帐户是一个具有
mysql.user
匹配表行user_name
的User
列和客户端主机 从中连接在Host
列。对于使用mysqladmin进行的密码更改,MySQL会在将密码存储在
mysql.user
表中之前自动进行哈希处理。
MySQL使数据库管理员能够手动终止帐户密码,并建立自动密码到期策略。
要手动过期密码,数据库管理员将使用以下 ALTER USER
语句:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;
此操作标记密码在相应的mysql.user
表行中过期 。
MySQL 5.7.4及更高版本中提供自动密码到期功能。该mysql.user
表指示每个帐户上次更改其密码时,如果客户端连接时间超过其允许的生命周期,服务器将自动将该密码视为已过期。这没有明确的手动密码到期。
该default_password_lifetime
系统变量定义了全球自动密码过期策略。它适用于使用MySQL内置的身份验证方法(使用的身份验证插件帐户的帐户mysql_native_password
, mysql_old_password
或 sha256_password
)。
默认 default_password_lifetime
值为0,禁用自动密码到期。如果值为default_password_lifetime
正整数N
,则表示允许的密码生存期; 密码必须每天更改 N
。
从MySQL 5.7.4到5.7.10,默认 default_password_lifetime
值为360(每年必须更改密码大约一次)。对于这些版本,请注意,如果您对default_password_lifetime
变量或个别用户帐户不进行任何更改 ,则所有用户密码将在360天后过期,并且在发生这种情况时,所有用户帐户都将以限制模式运行。连接到服务器的客户端(实际上是用户)将收到错误,指出必须更改密码: ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
但是,对于自动连接到服务器的客户端,例如由脚本创建的连接,这是很容易错过的。为避免这些客户端由于密码过期而突然停止工作,请确保更改这些客户端的密码过期设置,如下所示:
ALTER USER 'script'@'localhost' PASSWORD EXPIRE NEVER
或者,将default_password_lifetime
变量设置 为0
,从而禁用所有用户的自动密码到期。
例子:
-
要建立密码长达六个月的全局策略,请在选项文件中启动具有这些行的服务器:
[mysqld] default_password_lifetime=180
-
要建立密码永不过期的全局策略,设置
default_password_lifetime
为0:[mysqld] default_password_lifetime=0
-
default_password_lifetime
也可以在运行时更改(这需要SUPER
权限):SET GLOBAL default_password_lifetime = 180; SET GLOBAL default_password_lifetime = 0;
无论全球政策如何,都可以覆盖个人帐户ALTER USER
:
-
要求密码每90天更改一次:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
-
禁用密码到期:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
-
遵守全球到期政策:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;
PASSWORD EXPIRE DEFAULT
违反全球排放政策,并在mysql.user
表中将该password_lifetime
字段设置NULL
为指定的帐户。
这些ALTER USER
语句更新相应的mysql.user
表行。
当客户端成功连接时,服务器确定帐户密码是否过期:
-
服务器检查密码是否已手动过期,如果是,则限制会话。
-
否则,根据自动密码到期策略,服务器检查密码是否超过其使用寿命。如果是这样,服务器会认为密码过期并限制会话。
受限客户端以“ 沙箱模式 ”运行,这限制了客户端允许的操作(参见 第6.3.8节“密码到期和沙箱模式”)。由受限客户端执行的操作会导致错误,直到用户建立新的帐户密码:
mysql> SELECT 1;
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
mysql> ALTER USER USER() IDENTIFIED BY 'new_password';
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
这种受限制的操作模式允许 SET
语句,这在MySQL 5.7.6之前是有用的,如果 SET PASSWORD
必须使用,ALTER USER
而且帐户密码具有散列格式,需要 old_passwords
将其设置为与其默认值不同的值。
管理用户可以重置帐户密码,但该帐户的任何现有会话仍然受到限制。使用该帐户的客户端必须断开连接并重新连接,才能成功执行语句。
可以通过将密码设置为当前值来“ 重置 ”密码。作为一个好的策略,最好选择不同的密码
当客户端连接到MySQL服务器时,服务器使用客户端提供的用户名和客户端主机从mysql.user
表中选择适当的帐户行。然后,服务器对客户端进行身份验证,从帐户行确定哪个身份验证插件适用于客户端。服务器调用该插件来验证用户,并且该插件返回一个服务器状态,指示用户是否被允许连接。如果服务器找不到该插件,则会发生错误,连接尝试被拒绝。
可插拔认证支持两个重要功能:
-
外部认证: 可插拔身份验证使客户端可以使用适用于在其他位置存储凭据的身份验证方法的凭据连接到MySQL服务器
mysql.user
。例如,可以创建插件以使用外部身份验证方法,如PAM,Windows登录ID,LDAP或Kerberos。 -
代理用户:如果允许用户连接,认证插件可以向服务器返回不同于连接用户名称的用户名,以指示连接用户是另一用户(代理用户)的代理。当连接持续时,为了访问控制的目的,代理用户被视为拥有代理用户的权限。实际上,一个用户冒充另一个用户。有关更多信息,请参见第6.3.10节“代理用户”。
MySQL提供了几种验证插件:
-
执行本地认证的插件; 也就是基于在MySQL中引入可插拔认证之前使用的密码散列方法的认证。该
mysql_native_password
插件基于本机口令哈希方法实现身份验证。该mysql_old_password
插件基于较旧的(4.1之前)密码散列方法(并在MySQL 5.7.5中不推荐使用和删除)实现本机身份验证。请参见 第6.5.1.1节“本机可插拔认证”和 第6.5.1.2节“旧本地可插拔认证”。本地认证使用mysql_native_password
是新帐户的默认值,default_authentication_plugin
-
一个使用SHA-256密码散列进行认证的插件。此加密比本机认证可用的加密更强。请参见 第6.5.1.4节“SHA-256可插拔认证”。
-
将客户端插件发送到服务器而不进行散列或加密。该插件与服务器端插件一起使用,需要访问客户端用户所提供的密码。请参见 第6.5.1.5节“客户端Cleartext可插拔认证”。
-
使用PAM(可插拔认证模块)执行外部认证的插件,使MySQL服务器能够使用PAM来认证MySQL用户。此插件也支持代理用户。请参见 第6.5.1.6节“PAM可插拔认证”。
-
一个在Windows上执行外部验证的插件,使MySQL Server能够使用本机Windows服务来验证客户端连接。登录Windows的用户可以根据环境中的信息从MySQL客户端程序连接到服务器,而无需指定其他密码。此插件也支持代理用户。请参见 第6.5.1.7节“Windows可插拔认证”。
-
一个插件阻止所有客户端连接到任何使用它的帐户。此插件的用例包括必须能够以提升的权限执行存储的程序和视图而不将这些权限暴露给普通用户的帐户,以及不应允许直接登录但仅通过代理帐户访问的代理帐户。请参见 第6.5.1.8节“无登录可插拔认证”。
-
一个验证从本地主机通过Unix套接字文件连接的客户端的插件。请参见 第6.5.1.9节“套接字认证可插拔认证”。
-
一个测试插件,用于检查帐户凭据并记录服务器错误日志的成功或失败。此插件旨在用于测试和开发目的,以及如何编写身份验证插件的示例。请参见 第6.5.1.10节“测试可插拔认证”。
有关使用可插拔认证的当前限制的信息,包括哪些连接器支持哪些插件,请参见 第C.9节“可插拔认证的限制”。
第三方连接器开发人员应该阅读该部分,以确定连接器可以利用可插拔身份验证功能的程度以及采取何种步骤来实现更合规。
如果您有兴趣编写自己的身份验证插件,请参见第28.2.4.9节“编写验证插件”。
验证插件使用说明
本节提供安装和使用身份验证插件的一般说明。有关给定插件的具体说明,请参阅描述该插件的部分。
通常,可插拔身份验证在服务器和客户端都使用相应的插件,因此您可以使用如下所示的给定身份验证方法:
-
如有必要,请安装包含相应插件的插件库或库。在服务器主机上,安装包含服务器端插件的库,以便服务器可以使用它来验证客户端连接。同样,在每个客户端主机上,安装包含客户端插件的库,供客户端程序使用。内置的验证插件无需安装。
-
对于您创建的每个MySQL帐户,请指定用于身份验证的适当的服务器端插件。
-
当客户端连接时,服务器端插件告诉客户端程序哪个客户端插件用于验证。
在帐户使用服务器和客户端程序默认的身份验证方法的情况下,服务器不需要向客户端通信使用哪个客户端插件,客户端/服务器协商中的往返可以是避免。对于使用本机MySQL身份验证(mysql_native_password
或 mysql_old_password
)的帐户,这是真的。
该 选项可以在mysql命令行中指定,作为程序可以期望使用哪个客户端插件的提示,虽然如果与用户帐户关联的服务器端插件需要不同的客户端插件,服务器将重写此选项。 --default-auth=
plugin_name
如果客户端程序没有找到客户端插件,请指定一个 选项来指示插件所在的位置。 --plugin-dir=
dir_name
如果您使用该--skip-grant-tables
选项启动服务器, 即使加载,也不会使用身份验证插件,因为服务器不执行客户端身份验证并允许任何客户端进行连接。因为这是不安全的,您可能需要 --skip-grant-tables
结合使用 --skip-networking
以防止远程客户端连接
6.3.10代理用户
从版本5.7.6起,MySQL支持使用and 语句的ACCOUNT LOCK
和 ACCOUNT UNLOCK
子句 锁定和解锁用户帐户: CREATE USER
ALTER USER
-
当与
CREATE USER
这些条款一起使用时,这些条款指定新帐户的初始锁定状态。在没有任何一个条款的情况下,帐户将在未锁定状态下创建。 -
当与
ALTER USER
这些子句一起使用时,这些子句为现有帐户指定新的锁定状态。在没有任何一个条款的情况下,帐户锁定状态保持不变。
帐户锁定状态记录在表的 account_locked
列中 mysql.user
。输出 SHOW CREATE USER
表示帐户是否被锁定或解锁。
如果客户端尝试连接到锁定的帐户,则尝试失败。服务器增加 Locked_connects
状态变量,指示连接到锁定帐户的尝试次数,返回ER_ACCOUNT_HAS_BEEN_LOCKED
错误,并将消息写入错误日志中:
Access denied for user 'user_name'@'host_name'.
Account is locked.
锁定帐户不会影响能够使用假定已锁定帐户身份的代理用户进行连接。它也不影响执行存储程序或视图的能力,该视图具有DEFINER
命名锁定帐户的子句。也就是说,使用代理帐户或存储的程序或视图的能力不受锁定帐户的影响。
MySQL帐户对应于mysql.user
表中的行 。当客户端成功连接时,服务器将客户端认证到此表中的特定行。在User
与 Host
该行的列值唯一标识账号和对应 的账户名都写在SQL语句格式。 '
user_name
'@'host_name
'
用于验证客户端的帐户确定客户端具有哪些权限。通常,CURRENT_USER()
可以调用该 函数来确定哪个帐户是客户端用户。其值由 帐户的表行的列User
和 Host
列构成user
。
例如,空白的用户名与任何用户匹配,因此,''@'localhost'
允许客户端使用任何用户名从本地主机以匿名用户身份连接的帐户 。在这种情况下,如果客户端user1
从本地主机连接,USER()
并 CURRENT_USER()
返回不同的值:
mysql> SELECT USER(), CURRENT_USER();
+-----------------+----------------+
| USER() | CURRENT_USER() |
+-----------------+----------------+
| user1@localhost | @localhost |
+-----------------+----------------+
帐户的主机名称部分也可以包含通配符。如果主机名包含'%'
或 '_'
模式字符或使用网络掩码表示法,则该帐户可用于从多个主机连接的客户端,该CURRENT_USER()
值不会指示哪个主机名。例如,'user2'@'%.example.com'
可以使用该帐户 通过 域中的user2
任何主机进行连接 example.com
。如果user2
从连接remote.example.com
, USER()
并 CURRENT_USER()
返回不同的值:
mysql> SELECT USER(), CURRENT_USER();
+--------------------------+---------------------+
| USER() | CURRENT_USER() |
+--------------------------+---------------------+
| user2@remote.example.com | user2@%.example.com |
+--------------------------+---------------------+
如果应用程序必须调用 USER()
用户审核(例如,如果它从触发器内部进行审核),但还必须能够将该USER()
值与该user
表中的帐户相关联,则必须避免在User
or Host
列中包含通配符的帐户 。具体来说,不允许User
为空(创建一个匿名用户帐户),并且不允许值中的模式字符或网络掩码表示法Host
。所有帐户必须具有非空User
值和文字Host
值。
关于前面的例子, 应该更改帐户''@'localhost'
和 'user2'@'%.example.com'
不应使用通配符:
RENAME USER ''@'localhost' TO 'user1'@'localhost';
RENAME USER 'user2'@'%.example.com' TO 'user2'@'remote.example.com';
如果user2
必须能够从example.com
域中的多个主机连接,则每个主机应该有一个单独的帐户。
要从a CURRENT_USER()
或 USER()
值中提取用户名或主机名部分 ,请使用以下 SUBSTRING_INDEX()
函数:
mysql> SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',1);
+---------------------------------------+
| SUBSTRING_INDEX(CURRENT_USER(),'@',1) |
+---------------------------------------+
| user1 |
+---------------------------------------+
mysql> SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',-1);
+----------------------------------------+
| SUBSTRING_INDEX(CURRENT_USER(),'@',-1) |
+----------------------------------------+
| localhost |
+----------------------------------------+