MySQL 支持以下密码管理功能:
密码过期,要求定期更改密码。
密码重用限制,防止再次选择旧密码。
密码验证,要求更改密码时还必须指定要替换的当前密码。
双重密码,使客户端可以使用主密码或辅助密码进行连接。
密码强度评估,要求使用强密码。
随机密码生成,作为要求明确指定管理员指定的文字密码的替代方法。
密码失败跟踪,以便在连续多次输入错误密码的登录失败后启用临时帐户锁定。
以下各节介绍了这些功能,但密码强度评估除外,该功能是使用 validate_password
组件实现的,并在 第 8.4.3 节“密码验证组件” 中进行了介绍。
MySQL 使用 mysql
系统数据库中的表来实现密码管理功能。如果从早期版本升级 MySQL,则系统表可能不是最新的。在这种情况下,服务器会在启动过程中将类似于以下内容的消息写入错误日志(确切的数字可能会有所不同):
[ERROR] Column count of mysql.user is wrong. Expected
49, found 47. The table is probably corrupted
[Warning] ACL table mysql.password_history missing.
Some operations may fail.
要解决此问题,请执行 MySQL 升级过程。请参阅 第 3 章 升级 MySQL。在完成此操作之前,无法更改密码。
一些身份验证插件将帐户凭据存储在 MySQL 内部,即 mysql.user
系统表中:
caching_sha2_password
sha256_password
(已弃用)
本节中的大多数讨论都适用于此类身份验证插件,因为此处描述的大多数密码管理功能都是基于 MySQL 本身处理的内部凭据存储。其他身份验证插件将帐户凭据存储在 MySQL 外部。对于使用插件针对外部凭据系统执行身份验证的帐户,也必须针对该系统在外部处理密码管理。
例外情况是,用于登录失败跟踪和临时帐户锁定的选项适用于所有帐户,而不仅仅是使用内部凭据存储的帐户,因为 MySQL 能够评估任何帐户的登录尝试状态,而无论其使用的是内部凭据存储还是外部凭据存储。
有关各个身份验证插件的信息,请参阅 第 8.4.1 节“身份验证插件”。
MySQL 允许数据库管理员手动使帐户密码过期,并建立自动密码过期策略。可以在全局范围内建立过期策略,并且可以将单个帐户设置为遵循全局策略或使用特定的每帐户行为覆盖全局策略。
要手动使帐户密码过期,请使用 ALTER USER
语句:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;
此操作将 mysql.user
系统表中相应行中的密码标记为已过期。
根据策略的密码过期是自动的,并且基于密码有效期,对于给定帐户,密码有效期是从其最近一次密码更改的日期和时间开始评估的。mysql.user
系统表指示每个帐户的密码上次更改时间,如果密码的有效期超过其允许的生存期,则服务器会在客户端连接时自动将其视为已过期。这无需显式的手动密码过期即可工作。
要全局建立自动密码过期策略,请使用 default_password_lifetime
系统变量。其默认值为 0,表示禁用自动密码过期。如果 default_password_lifetime
的值为正整数 N
,则表示允许的密码生存期,即必须每 N
天更改一次密码。
例子
要建立一个全局策略,使密码的生存期约为六个月,请在服务器
my.cnf
文件中使用以下几行启动服务器[mysqld] default_password_lifetime=180
要建立一个全局策略,使密码永不过期,请将
default_password_lifetime
设置为 0[mysqld] default_password_lifetime=0
default_password_lifetime
也可以在运行时设置并持久化SET PERSIST default_password_lifetime = 180; SET PERSIST default_password_lifetime = 0;
SET PERSIST
为正在运行的 MySQL 实例设置一个值。它还会保存该值,以便在后续服务器重启时继续使用;请参阅 第 15.7.6.1 节“用于变量赋值的 SET 语法”。要更改正在运行的 MySQL 实例的值而不将其保留到后续重启,请使用GLOBAL
关键字而不是PERSIST
。
全局密码过期策略适用于所有尚未设置为覆盖它的帐户。要为单个帐户建立策略,请使用 CREATE USER
和 ALTER USER
语句的 PASSWORD EXPIRE
选项。请参阅 第 15.7.1.3 节“CREATE USER 语句” 和 第 15.7.1.1 节“ALTER USER 语句”。
特定于帐户的语句示例
要求每 90 天更改一次密码
CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY; ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
此过期选项将覆盖语句中命名的所有帐户的全局策略。
禁用密码过期
CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER; ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
此过期选项将覆盖语句中命名的所有帐户的全局策略。
遵循语句中命名的所有帐户的全局过期策略
CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT; ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;
当客户端成功连接时,服务器会确定帐户密码是否已过期
服务器会检查密码是否已手动过期。
否则,服务器会根据自动密码过期策略检查密码使用时间是否超过其允许的生存期。如果是,则服务器会将密码视为已过期。
如果密码已过期(无论是手动还是自动过期),服务器都会断开客户端连接或限制允许其执行的操作(请参阅 第 8.2.16 节“服务器对过期密码的处理”)。受限客户端执行的操作会导致错误,直到用户建立新的帐户密码为止
mysql> SELECT 1;
ERROR 1820 (HY000): You must reset your password using ALTER USER
statement before executing this statement.
mysql> ALTER USER USER() IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
客户端重置密码后,服务器将为该会话以及使用该帐户的后续连接恢复正常访问。管理用户也可以重置帐户密码,但该帐户的任何现有受限会话仍将保持受限状态。使用该帐户的客户端必须断开连接并重新连接,才能成功执行语句。
尽管可以通过将过期密码设置为其当前值来 “重置” 它,但作为一项良好的策略,最好选择一个不同的密码。DBA 可以通过建立适当的密码重用策略来强制执行不重用。请参阅 密码重用策略。
MySQL 允许对重用以前的密码施加限制。可以根据密码更改次数、经过的时间或两者来建立重用限制。可以全局建立重用策略,并且可以将各个帐户设置为遵循全局策略或使用特定于帐户的行为覆盖全局策略。
帐户的密码历史记录包含其过去分配的密码。MySQL 可以限制从该历史记录中选择新密码
如果某个帐户根据密码更改次数受到限制,则新密码不能从指定数量的最新密码中选择。例如,如果密码更改的最小次数设置为 3,则新密码不能与最近 3 个密码中的任何一个相同。
如果某个帐户根据经过的时间受到限制,则新密码不能从历史记录中比指定天数更新的密码中选择。例如,如果密码重用间隔设置为 60,则新密码不能是过去 60 天内先前选择的密码之一。
空密码不计入密码历史记录,并且可以随时重用。
要全局建立密码重用策略,请使用 password_history
和 password_reuse_interval
系统变量。
例子
要禁止重用最近 6 个密码或比 365 天更新的密码,请将以下几行放入服务器
my.cnf
文件中[mysqld] password_history=6 password_reuse_interval=365
要在运行时设置并持久化变量,请使用如下语句
SET PERSIST password_history = 6; SET PERSIST password_reuse_interval = 365;
SET PERSIST
为正在运行的 MySQL 实例设置一个值。它还会保存该值,以便在后续服务器重启时继续使用;请参阅 第 15.7.6.1 节“用于变量赋值的 SET 语法”。要更改正在运行的 MySQL 实例的值而不将其保留到后续重启,请使用GLOBAL
关键字而不是PERSIST
。
全局密码重用策略适用于所有尚未设置为覆盖它的帐户。要为单个帐户建立策略,请使用 CREATE USER
和 ALTER USER
语句的 PASSWORD HISTORY
和 PASSWORD REUSE INTERVAL
选项。请参阅 第 15.7.1.3 节“CREATE USER 语句” 和 第 15.7.1.1 节“ALTER USER 语句”。
特定于帐户的语句示例
要求在允许重用之前至少更改 5 次密码
CREATE USER 'jeffrey'@'localhost' PASSWORD HISTORY 5; ALTER USER 'jeffrey'@'localhost' PASSWORD HISTORY 5;
此历史长度选项将覆盖语句中命名的所有帐户的全局策略。
要求在允许重用之前至少经过 365 天
CREATE USER 'jeffrey'@'localhost' PASSWORD REUSE INTERVAL 365 DAY; ALTER USER 'jeffrey'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;
此时间间隔选项将覆盖语句中命名的所有帐户的全局策略。
要结合这两种类型的重用限制,请同时使用
PASSWORD HISTORY
和PASSWORD REUSE INTERVAL
CREATE USER 'jeffrey'@'localhost' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 365 DAY; ALTER USER 'jeffrey'@'localhost' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 365 DAY;
这些选项将覆盖语句中命名的所有帐户的两种全局策略重用限制。
遵循这两种类型的重用限制的全局策略
CREATE USER 'jeffrey'@'localhost' PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT; ALTER USER 'jeffrey'@'localhost' PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT;
可以通过指定要替换的当前密码来要求验证更改帐户密码的尝试。这使 DBA 能够防止用户在不证明他们知道当前密码的情况下更改密码。否则,可能会发生此类更改,例如,如果一个用户暂时离开终端会话而未注销,而恶意用户使用该会话更改了原始用户的 MySQL 密码。这可能会导致不幸的后果
原始用户将无法访问 MySQL,直到管理员重置帐户密码。
在重置密码之前,恶意用户可以使用良性用户更改后的凭据访问 MySQL。
可以全局建立密码验证策略,并且可以将各个帐户设置为遵循全局策略或使用特定于帐户的行为覆盖全局策略。
对于每个帐户,其 mysql.user
行指示是否存在特定于帐户的设置,该设置要求验证密码更改尝试的当前密码。该设置由 CREATE USER
和 ALTER USER
语句的 PASSWORD REQUIRE
选项建立
如果帐户设置为
PASSWORD REQUIRE CURRENT
,则密码更改必须指定当前密码。如果帐户设置为
PASSWORD REQUIRE CURRENT OPTIONAL
,则密码更改可以指定也可以不指定当前密码。如果帐户设置为
PASSWORD REQUIRE CURRENT DEFAULT
,则password_require_current
系统变量将确定该帐户的验证要求策略如果启用了
password_require_current
,则密码更改必须指定当前密码。如果禁用了
password_require_current
,则密码更改可以指定也可以不指定当前密码。
换句话说,如果帐户设置不是 PASSWORD REQUIRE CURRENT DEFAULT
,则帐户设置优先于 password_require_current
系统变量建立的全局策略。否则,该帐户将遵循 password_require_current
设置。
默认情况下,密码验证是可选的:password_require_current
被禁用,并且使用 PASSWORD REQUIRE
选项创建的帐户默认为 PASSWORD REQUIRE CURRENT DEFAULT
。
下表显示了每个帐户的设置如何与 password_require_current
系统变量值交互以确定帐户密码验证要求策略。
表 8.10 密码验证策略
每个帐户的设置 | password_require_current 系统变量 | 密码更改是否需要当前密码? |
---|---|---|
PASSWORD REQUIRE CURRENT |
OFF |
是 |
PASSWORD REQUIRE CURRENT |
ON |
是 |
PASSWORD REQUIRE CURRENT OPTIONAL |
OFF |
否 |
PASSWORD REQUIRE CURRENT OPTIONAL |
ON |
否 |
PASSWORD REQUIRE CURRENT DEFAULT |
OFF |
否 |
PASSWORD REQUIRE CURRENT DEFAULT |
ON |
是 |
无论验证要求策略如何,特权用户都可以更改任何帐户密码,而无需指定当前密码。特权用户是指具有全局 CREATE USER
权限或 mysql
系统数据库的 UPDATE
权限的用户。
要全局建立密码验证策略,请使用 password_require_current
系统变量。其默认值为 OFF
,因此不要求帐户密码更改指定当前密码。
例子
要建立一个全局策略,要求密码更改必须指定当前密码,请在服务器
my.cnf
文件中使用以下几行启动服务器[mysqld] password_require_current=ON
要在运行时设置并持久化
password_require_current
,请使用以下语句之一SET PERSIST password_require_current = ON; SET PERSIST password_require_current = OFF;
SET PERSIST
为正在运行的 MySQL 实例设置一个值。它还会保存该值,以便在后续服务器重启时继续使用;请参阅 第 15.7.6.1 节“用于变量赋值的 SET 语法”。要更改正在运行的 MySQL 实例的值而不将其保留到后续重启,请使用GLOBAL
关键字而不是PERSIST
。
全局密码验证要求策略适用于所有尚未设置为覆盖它的帐户。要为单个帐户建立策略,请使用 CREATE USER
和 ALTER USER
语句的 PASSWORD REQUIRE
选项。请参阅 第 15.7.1.3 节“CREATE USER 语句” 和 第 15.7.1.1 节“ALTER USER 语句”。
特定于帐户的语句示例
要求密码更改指定当前密码
CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT; ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;
此验证选项将覆盖语句中命名的所有帐户的全局策略。
不要求密码更改指定当前密码(可以提供也可以不提供当前密码)
CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL; ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;
此验证选项将覆盖语句中命名的所有帐户的全局策略。
遵循语句中命名的所有帐户的全局密码验证要求策略
CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT DEFAULT; ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT DEFAULT;
当用户使用 ALTER USER
或 SET PASSWORD
语句更改密码时,需要验证当前密码。示例使用 ALTER USER
,它优于 SET PASSWORD
,但此处描述的原则对这两个语句都适用。
在更改密码的语句中,REPLACE
子句指定要替换的当前密码。例如:
更改当前用户的密码:
ALTER USER USER() IDENTIFIED BY 'auth_string' REPLACE 'current_auth_string';
更改指定用户的密码:
ALTER USER 'jeffrey'@'localhost' IDENTIFIED BY 'auth_string' REPLACE 'current_auth_string';
更改指定用户的身份验证插件和密码:
ALTER USER 'jeffrey'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'auth_string' REPLACE 'current_auth_string';
REPLACE
子句的工作原理如下:
如果帐户的密码更改需要指定当前密码(作为对尝试更改密码的用户确实知道当前密码的验证),则必须提供
REPLACE
。如果帐户的密码更改可以但不需要指定当前密码,则
REPLACE
是可选的。如果指定了
REPLACE
,则它必须指定正确的当前密码,否则会发生错误。即使REPLACE
是可选的,也是如此。REPLACE
只能在更改当前用户的帐户密码时指定。(这意味着在刚才显示的示例中,除非当前用户是jeffrey
,否则显式命名jeffrey
帐户的语句将失败。)即使特权用户尝试为其他用户进行更改也是如此;但是,此类用户可以更改任何密码而无需指定REPLACE
。二进制日志中省略了
REPLACE
,以避免将明文密码写入其中。
用户帐户允许拥有双重密码,指定为主密码和辅助密码。双重密码功能可以在以下情况下无缝执行凭据更改:
一个系统拥有大量的 MySQL 服务器,可能涉及复制。
多个应用程序连接到不同的 MySQL 服务器。
必须定期更改应用程序用于连接服务器的帐户的凭据。
考虑在上述情况下,当一个帐户只允许使用一个密码时,如何执行凭据更改。在这种情况下,必须密切配合帐户密码更改的时间并在所有服务器上传播,以及所有使用该帐户的应用程序何时更新为使用新密码。此过程可能涉及服务器或应用程序不可用的停机时间。
使用双重密码,可以更轻松地分阶段进行凭据更改,而无需密切配合,也无需停机:
为每个受影响的帐户,在服务器上建立一个新的主密码,保留当前密码作为辅助密码。这使得服务器能够识别每个帐户的主密码或辅助密码,而应用程序可以继续使用与以前相同的密码(现在是辅助密码)连接到服务器。
在密码更改传播到所有服务器之后,修改使用任何受影响帐户的应用程序,以使用帐户主密码进行连接。
在所有应用程序都从辅助密码迁移到主密码之后,就不再需要辅助密码,可以将其丢弃。此更改传播到所有服务器后,只能使用每个帐户的主密码进行连接。现在,凭据更改已完成。
MySQL 使用保存和丢弃辅助密码的语法来实现双重密码功能:
ALTER USER
和SET PASSWORD
语句的RETAIN CURRENT PASSWORD
子句,在您分配新的主密码时,会将帐户当前密码保存为其辅助密码。ALTER USER
的DISCARD OLD PASSWORD
子句会丢弃帐户辅助密码,只保留主密码。
假设,对于前面描述的凭据更改场景,应用程序使用名为 'appuser1'@'host1.example.com'
的帐户连接到服务器,并且该帐户的密码要从 '
更改为 password_a
''
。password_b
'
要执行此凭据更改,请使用 ALTER USER
,如下所示:
在每个不是副本的服务器上,将
'
建立为新的password_b
'appuser1
主密码,保留当前密码作为辅助密码:ALTER USER 'appuser1'@'host1.example.com' IDENTIFIED BY 'password_b' RETAIN CURRENT PASSWORD;
等待密码更改复制到整个系统的所有副本。
修改每个使用
appuser1
帐户的应用程序,使其使用密码'
而不是password_b
''
连接到服务器。password_a
'此时,不再需要辅助密码。在每个不是副本的服务器上,丢弃辅助密码:
ALTER USER 'appuser1'@'host1.example.com' DISCARD OLD PASSWORD;
在丢弃密码的更改复制到所有副本后,凭据更改就完成了。
RETAIN CURRENT PASSWORD
和 DISCARD OLD PASSWORD
子句具有以下效果:
RETAIN CURRENT PASSWORD
将帐户当前密码保留为其辅助密码,替换任何现有的辅助密码。新密码成为主密码,但客户端可以使用该帐户使用主密码或辅助密码连接到服务器。(例外:如果ALTER USER
或SET PASSWORD
语句指定的新密码为空,则即使指定了RETAIN CURRENT PASSWORD
,辅助密码也会变为空。)如果为具有空主密码的帐户指定
RETAIN CURRENT PASSWORD
,则语句将失败。如果一个帐户有辅助密码,并且您在不指定
RETAIN CURRENT PASSWORD
的情况下更改其主密码,则辅助密码保持不变。对于
ALTER USER
,如果您更改分配给帐户的身份验证插件,则辅助密码将被丢弃。如果您更改身份验证插件并指定RETAIN CURRENT PASSWORD
,则语句将失败。对于
ALTER USER
,DISCARD OLD PASSWORD
会丢弃辅助密码(如果存在)。该帐户仅保留其主密码,客户端只能使用主密码连接到服务器。
修改辅助密码的语句需要以下权限:
要对您自己的帐户使用
ALTER USER
和SET PASSWORD
语句中的RETAIN CURRENT PASSWORD
或DISCARD OLD PASSWORD
子句,需要APPLICATION_PASSWORD_ADMIN
权限。因为大多数用户只需要一个密码,所以需要该权限来操作您自己的辅助密码。如果要允许某个帐户操作所有帐户的辅助密码,则应为其授予
CREATE USER
权限,而不是APPLICATION_PASSWORD_ADMIN
。
CREATE USER
、ALTER USER
和 SET PASSWORD
语句能够为用户帐户生成随机密码,作为要求管理员明确指定文字密码的替代方法。有关语法详情,请参阅每个语句的描述。本节描述了生成的随机密码的共同特征。
默认情况下,生成的随机密码长度为 20 个字符。此长度由 generated_random_password_length
系统变量控制,其范围为 5 到 255。
对于语句为其生成随机密码的每个帐户,该语句都会将密码存储在 mysql.user
系统表中,并根据帐户身份验证插件进行适当的哈希处理。该语句还会在结果集的一行中返回明文密码,使其可供执行该语句的用户或应用程序使用。结果集列名为 user
、host
、generated password
和 auth_factor
,分别表示标识 mysql.user
系统表中受影响行的用户名和主机名值、明文生成的密码以及显示的密码值适用的身份验证因子。
mysql> CREATE USER
'u1'@'localhost' IDENTIFIED BY RANDOM PASSWORD,
'u2'@'%.example.com' IDENTIFIED BY RANDOM PASSWORD,
'u3'@'%.org' IDENTIFIED BY RANDOM PASSWORD;
+------+---------------+----------------------+-------------+
| user | host | generated password | auth_factor |
+------+---------------+----------------------+-------------+
| u1 | localhost | iOeqf>Mh9:;XD&qn(Hl} | 1 |
| u2 | %.example.com | sXTSAEvw3St-R+_-C3Vb | 1 |
| u3 | %.org | nEVe%Ctw/U/*Md)Exc7& | 1 |
+------+---------------+----------------------+-------------+
mysql> ALTER USER
'u1'@'localhost' IDENTIFIED BY RANDOM PASSWORD,
'u2'@'%.example.com' IDENTIFIED BY RANDOM PASSWORD;
+------+---------------+----------------------+-------------+
| user | host | generated password | auth_factor |
+------+---------------+----------------------+-------------+
| u1 | localhost | Seiei:&cw}8]@3OA64vh | 1 |
| u2 | %.example.com | j@&diTX80l8}(NiHXSae | 1 |
+------+---------------+----------------------+-------------+
mysql> SET PASSWORD FOR 'u3'@'%.org' TO RANDOM;
+------+-------+----------------------+-------------+
| user | host | generated password | auth_factor |
+------+-------+----------------------+-------------+
| u3 | %.org | n&cz2xF;P3!U)+]Vw52H | 1 |
+------+-------+----------------------+-------------+
为帐户生成随机密码的 CREATE USER
、ALTER USER
或 SET PASSWORD
语句将被写入二进制日志,作为带有 IDENTIFIED WITH
子句的 auth_plugin
AS 'auth_string
'CREATE USER
或 ALTER USER
语句,其中 auth_plugin
是帐户身份验证插件,'
是帐户哈希密码值。auth_string
'
如果安装了 validate_password
组件,则其实现的策略对生成的密码没有影响。(密码验证的目的是帮助人们创建更好的密码。)
管理员可以配置用户帐户,以便在连续登录失败次数过多时导致临时帐户锁定。
在这种情况下,“登录失败”是指客户端在连接尝试期间未能提供正确的密码。它不包括由于未知用户或网络问题等原因导致的连接失败。对于具有双重密码的帐户(请参阅 双重密码支持),任何一个帐户密码都算作正确。
可以使用 CREATE USER
和 ALTER USER
语句的 FAILED_LOGIN_ATTEMPTS
和 PASSWORD_LOCK_TIME
选项,为每个帐户配置所需的登录失败次数和锁定时间。例如:
CREATE USER 'u1'@'localhost' IDENTIFIED BY 'password'
FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3;
ALTER USER 'u2'@'localhost'
FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME UNBOUNDED;
当连续登录失败次数过多时,客户端会收到如下错误:
ERROR 3957 (HY000): Access denied for user user.
Account is blocked for D day(s) (R day(s) remaining)
due to N consecutive failed logins.
选项的使用方法如下:
FAILED_LOGIN_ATTEMPTS
N
此选项指示是否跟踪指定了错误密码的帐户登录尝试。数字
N
指定导致临时帐户锁定的连续错误密码次数。PASSWORD_LOCK_TIME {
N
| UNBOUNDED}此选项指示在连续登录尝试提供错误密码的次数过多后锁定帐户的时间。该值是一个数字
N
,用于指定帐户保持锁定状态的天数,或者UNBOUNDED
用于指定当帐户进入暂时锁定状态时,该状态的持续时间是无限制的,并且不会结束,直到帐户被解锁。稍后将描述解锁发生的条件。
每个选项允许的 N
值的范围为 0 到 32767。值为 0 将禁用该选项。
失败登录跟踪和临时帐户锁定具有以下特征:
要对帐户进行失败登录跟踪和临时锁定,其
FAILED_LOGIN_ATTEMPTS
和PASSWORD_LOCK_TIME
选项都必须为非零值。对于
CREATE USER
,如果未指定FAILED_LOGIN_ATTEMPTS
或PASSWORD_LOCK_TIME
,则其隐式默认值为 0,适用于语句命名的所有帐户。这意味着禁用了失败登录跟踪和临时帐户锁定。对于
ALTER USER
,如果未指定FAILED_LOGIN_ATTEMPTS
或PASSWORD_LOCK_TIME
,则其值对于语句命名的所有帐户保持不变。要进行临时帐户锁定,密码失败必须是连续的。在达到失败登录的
FAILED_LOGIN_ATTEMPTS
值之前发生的任何成功登录都会导致失败计数重置。例如,如果FAILED_LOGIN_ATTEMPTS
为 4,并且已经发生三次连续的密码失败,则还需要一次失败才能开始锁定。但是,如果下一次登录成功,则该帐户的失败登录计数将重置,因此再次需要四次连续的失败才能进行锁定。一旦开始临时锁定,即使使用正确的密码也无法成功登录,直到锁定持续时间结束或帐户通过以下讨论中列出的帐户重置方法之一解锁。
当服务器读取授权表时,它将为每个帐户初始化状态信息,包括是否启用了失败登录跟踪,帐户当前是否被临时锁定以及如果是,则锁定开始的时间,以及如果帐户未被锁定,则在临时锁定发生之前的失败次数。
可以重置帐户的状态信息,这意味着失败登录计数将重置,并且如果当前被临时锁定,则帐户将被解锁。帐户重置可以针对所有帐户进行全局重置,也可以针对每个帐户进行重置。
在以下任何情况下都会发生所有帐户的全局重置:
服务器重启。
执行
FLUSH PRIVILEGES
。(使用--skip-grant-tables
启动服务器会导致不读取授权表,从而禁用失败登录跟踪。在这种情况下,第一次执行FLUSH PRIVILEGES
会导致服务器读取授权表并启用失败登录跟踪,此外还会重置所有帐户。)
在以下任何情况下都会发生每个帐户的重置:
帐户成功登录。
锁定持续时间结束。在这种情况下,失败登录计数将在下一次登录尝试时重置。
为该帐户执行
ALTER USER
语句,将FAILED_LOGIN_ATTEMPTS
或PASSWORD_LOCK_TIME
(或两者)设置为任何值(包括当前选项值),或者为该帐户执行ALTER USER ... UNLOCK
语句。该帐户的其他
ALTER USER
语句对其当前的失败登录计数或锁定状态没有影响。
失败登录跟踪与用于检查凭据的登录帐户相关联。如果正在使用用户代理,则会对代理用户而不是被代理用户进行跟踪。也就是说,跟踪与 USER()
指示的帐户相关联,而不是与 CURRENT_USER()
指示的帐户相关联。有关代理用户和被代理用户之间区别的信息,请参见 第 8.2.19 节“代理用户”。