文档主页
MySQL 8.4 参考手册
相关文档 下载本手册

MySQL 8.4 参考手册  /  ...  /  密码管理

8.2.15 密码管理

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

  • mysql_native_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)

客户端重置密码后,服务器会为该会话以及使用该帐户的后续连接恢复正常访问。管理员用户也可以重置帐户密码,但该帐户的任何现有受限会话将保持受限状态。使用该帐户的客户端必须断开连接并重新连接,然后才能成功执行语句。

注意

尽管可以通过将过期密码设置为其当前值来“重置”它,但作为一项良好的策略,最好选择一个不同的密码。数据库管理员可以通过建立适当的密码重用策略来强制执行不重用。请参阅 密码重用策略。

密码重用策略

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;

密码验证要求策略

可以通过指定要替换的当前密码来要求验证更改帐户密码的尝试。这使数据库管理员能够防止用户在未证明自己知道当前密码的情况下更改密码。否则可能会发生此类更改,例如,如果一个用户暂时离开终端会话而未注销,而恶意用户使用该会话更改原始用户的 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 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 服务器。

  • 必须定期更改应用程序用来连接服务器的帐户的凭据。

考虑在前面类型的情况下,当帐户只允许使用一个密码时,如何执行凭据更改。在这种情况下,必须密切配合帐户密码更改的时间,并在所有服务器上传播,以及何时更新使用该帐户的所有应用程序以使用新密码。此过程可能涉及服务器或应用程序不可用的停机时间。

使用双重密码,可以更轻松地分阶段进行凭据更改,而无需密切配合,也不需要停机时间:

  1. 对于每个受影响的帐户,在服务器上建立一个新的主密码,将当前密码保留为辅助密码。这使得服务器能够识别每个帐户的主密码或辅助密码,而应用程序可以继续使用与以前相同的密码(现在是辅助密码)连接到服务器。

  2. 在密码更改传播到所有服务器后,修改使用任何受影响帐户的应用程序,以使用帐户主密码进行连接。

  3. 在所有应用程序都从辅助密码迁移到主密码后,就不再需要辅助密码,可以将其丢弃。此更改传播到所有服务器后,只能使用每个帐户的主密码进行连接。现在,凭据更改已完成。

MySQL 使用保存和丢弃辅助密码的语法来实现双重密码功能:

  • ALTER USER 和 SET PASSWORD 语句的 RETAIN CURRENT PASSWORD 子句在您分配新的主密码时,将帐户当前密码保存为其辅助密码。

  • ALTER USER 的 DISCARD OLD PASSWORD 子句丢弃帐户辅助密码,只保留主密码。

假设,对于前面描述的凭据更改方案,应用程序使用名为 'appuser1'@'host1.example.com' 的帐户连接到服务器,并且该帐户的密码将从 'password_a' 更改为 'password_b'。

要执行此凭据更改,请使用 ALTER USER,如下所示:

  1. 在每个不是副本的服务器上,将 'password_b' 建立为新的 appuser1 主密码,将当前密码保留为辅助密码:

    ALTER USER 'appuser1'@'host1.example.com'
      IDENTIFIED BY 'password_b'
      RETAIN CURRENT PASSWORD;
  2. 等待密码更改复制到整个系统中的所有副本。

  3. 修改使用 appuser1 帐户的每个应用程序,使其使用密码 'password_b' 而不是 'password_a' 连接到服务器。

  4. 此时,不再需要辅助密码。在每个不是副本的服务器上,丢弃辅助密码:

    ALTER USER 'appuser1'@'host1.example.com'
      DISCARD OLD PASSWORD;
  5. 在丢弃密码更改复制到所有副本后,凭据更改就完成了。

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 丢弃辅助密码(如果存在)。该帐户只保留其主密码,客户端只能使用主密码连接到服务器。

修改辅助密码的语句需要以下权限:

随机密码生成

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 节,“代理用户”。