6.2.15 Password Management密码管理

MySQL supports these password-management capabilities:MySQL支持以下密码管理功能:

The following sections describe these capabilities, except password strength assessment, which is implemented using the validate_password component and is described in Section 6.4.3, “The Password Validation Component”.以下部分描述了这些功能,但密码强度评估除外,该评估是使用validate_password组件实现的,并在第6.4.3节,“密码验证组件”中进行了描述。

Important重要

MySQL implements password-management capabilities using tables in the mysql system database. If you upgrade MySQL from an earlier version, your system tables might not be up to date. MySQL使用mysql系统数据库中的表实现密码管理功能。如果你从早期版本升级MySQL,你的系统表可能不是最新的。In that case, the server writes messages similar to these to the error log during the startup process (the exact numbers may vary):在这种情况下,服务器在启动过程中将类似于以下内容的消息写入错误日志(确切数字可能会有所不同):

[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.

To correct the issue, perform the MySQL upgrade procedure. 要更正此问题,请执行MySQL升级过程。See Section 2.11, “Upgrading MySQL”. Until this is done, password changes are not possible.请参阅第2.11节,“升级MySQL”。在此之前,无法更改密码。

Internal Versus External Credentials Storage内部与外部凭据存储

Some authentication plugins store account credentials internally to MySQL, in the mysql.user system table:一些身份验证插件将帐户凭据存储在MySQL内部的mysql.user系统表中:

  • mysql_native_password

  • caching_sha2_password

  • sha256_password

Most discussion in this section applies to such authentication plugins because most password-management capabilities described here are based on internal credentials storage handled by MySQL itself. 本节中的大多数讨论都适用于此类身份验证插件,因为这里描述的大多数密码管理功能都是基于MySQL本身处理的内部凭据存储。Other authentication plugins store account credentials externally to MySQL. 其他身份验证插件将帐户凭据存储在MySQL外部。For accounts that use plugins that perform authentication against an external credentials system, password management must be handled externally against that system as well.对于使用插件对外部凭据系统执行身份验证的帐户,密码管理也必须在外部对该系统进行处理。

The exception is that the options for failed-login tracking and temporary account locking apply to all accounts, not just accounts that use internal credentials storage, because MySQL is able to assess the status of login attempts for any account no matter whether it uses internal or external credentials storage.例外的是,登录跟踪失败和临时帐户锁定的选项适用于所有帐户,而不仅仅是使用内部凭据存储的帐户,因为MySQL能够评估任何帐户的登录尝试状态,无论它是使用内部还是外部凭据存储。

For information about individual authentication plugins, see Section 6.4.1, “Authentication Plugins”.有关单个身份验证插件的信息,请参阅第6.4.1节,“身份验证插件”

Password Expiration Policy密码过期策略

MySQL enables database administrators to expire account passwords manually, and to establish a policy for automatic password expiration. Expiration policy can be established globally, and individual accounts can be set to either defer to the global policy or override the global policy with specific per-account behavior.MySQL使数据库管理员能够手动使帐户密码过期,并建立自动密码过期策略。过期策略可以在全局范围内建立,并且可以将单个帐户设置为遵守全局策略或用特定的每个帐户行为覆盖全局策略。

To expire an account password manually, use the ALTER USER statement:要手动使帐户密码过期,请使用ALTER USER语句:

ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;

This operation marks the password expired in the corresponding row in the mysql.user system table.此操作在mysql.user系统表中的相应行中标记密码已过期。

Password expiration according to policy is automatic and is based on password age, which for a given account is assessed from the date and time of its most recent password change. 根据策略,密码过期是自动的,并且基于密码期限,对于给定的帐户,密码期限从其最近一次密码更改的日期和时间开始评估。The mysql.user system table indicates for each account when its password was last changed, and the server automatically treats the password as expired at client connection time if its age is greater than its permitted lifetime. mysql.user系统表为每个帐户指示其密码上次更改的时间,如果密码的年龄大于其允许的生存期,服务器会自动将密码视为在客户端连接时过期。This works with no explicit manual password expiration.这适用于没有明确手动密码过期的情况。

To establish automatic password-expiration policy globally, use the default_password_lifetime system variable. 要全局建立自动密码过期策略,请使用default_password_lifetime系统变量。Its default value is 0, which disables automatic password expiration. 其默认值为0,表示禁用自动密码过期。If the value of default_password_lifetime is a positive integer N, it indicates the permitted password lifetime, such that passwords must be changed every N days.如果default_password_lifetime的值是正整数N,则表示允许的密码生存期,因此密码必须每N天更改一次。

Examples:示例:

  • To establish a global policy that passwords have a lifetime of approximately six months, start the server with these lines in a server my.cnf file:要建立密码有效期约为六个月的全局策略,请在服务器my.cnf文件中使用以下行启动服务器:

    [mysqld]
    default_password_lifetime=180
  • To establish a global policy such that passwords never expire, set default_password_lifetime to 0:要建立全局策略以使密码永不过期,请将default_password_lifetime设置为0:

    [mysqld]
    default_password_lifetime=0
  • default_password_lifetime can also be set and persisted at runtime:default_password_lifetime也可以在运行时设置和持久化:

    SET PERSIST default_password_lifetime = 180;
    SET PERSIST default_password_lifetime = 0;

    SET PERSIST sets the value for the running MySQL instance. SET PERSIST设置正在运行的MySQL实例的值。It also saves the value to carry over to subsequent server restarts; see Section 13.7.6.1, “SET Syntax for Variable Assignment”. 它还保存了值,以结转至后续的服务器重启;请参阅第13.7.6.1节,“变量赋值的SET语法”To change the value for the running MySQL instance without having it carry over to subsequent restarts, use the GLOBAL keyword rather than PERSIST.要更改正在运行的MySQL实例的值而不将其转移到后续重启,请使用GLOBAL关键字而不是PERSIST

The global password-expiration policy applies to all accounts that have not been set to override it. 全局密码过期策略适用于所有尚未设置为覆盖它的帐户。To establish policy for individual accounts, use the PASSWORD EXPIRE option of the CREATE USER and ALTER USER statements. 要为单个帐户建立策略,请使用CREATE USERALTER USER语句的PASSWORD EXPIRE选项。See Section 13.7.1.3, “CREATE USER Statement”, and Section 13.7.1.1, “ALTER USER Statement”.请参阅第13.7.1.3节,“CREATE USER语句”第13.7.1.1节,“ALTER USER语句”

Example account-specific statements:特定账户对账单示例:

  • Require the password to be changed every 90 days:要求每90天更改一次密码:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

    This expiration option overrides the global policy for all accounts named by the statement.此过期选项将覆盖该语句命名的所有帐户的全局策略。

  • Disable password expiration:禁用密码过期:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;

    This expiration option overrides the global policy for all accounts named by the statement.此过期选项将覆盖该语句命名的所有帐户的全局策略。

  • Defer to the global expiration policy for all accounts named by the statement:对声明中指定的所有帐户遵守全局过期策略:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;

When a client successfully connects, the server determines whether the account password has expired:当客户端成功连接时,服务器会确定帐户密码是否已过期:

  • The server checks whether the password has been manually expired.服务器检查密码是否已手动过期。

  • Otherwise, the server checks whether the password age is greater than its permitted lifetime according to the automatic password expiration policy. If so, the server considers the password expired.否则,服务器将根据自动密码过期策略检查密码期限是否大于其允许的生存期。如果是这样,服务器将认为密码已过期。

If the password is expired (whether manually or automatically), the server either disconnects the client or restricts the operations permitted to it (see Section 6.2.16, “Server Handling of Expired Passwords”). 如果密码过期(无论是手动还是自动),服务器要么断开客户端的连接,要么限制允许的操作(参阅第6.2.16节,“服务器处理过期密码”)。Operations performed by a restricted client result in an error until the user establishes a new account password:受限客户端执行的操作会导致错误,直到用户建立新的帐户密码:

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)

After the client resets the password, the server restores normal access for the session, as well as for subsequent connections that use the account. 客户端重置密码后,服务器将恢复会话以及使用该帐户的后续连接的正常访问。It is also possible for an administrative user to reset the account password, but any existing restricted sessions for that account remain restricted. 管理用户也可以重置帐户密码,但该帐户的任何现有受限会话仍受限制。A client using the account must disconnect and reconnect before statements can be executed successfully.使用该帐户的客户端必须断开连接并重新连接,才能成功执行语句。

Note注意

Although it is possible to reset an expired password by setting it to its current value, it is preferable, as a matter of good policy, to choose a different password. 虽然可以通过将过期的密码设置为当前值来“重置”它,但作为一项良好的政策,最好选择其他密码。DBAs can enforce non-reuse by establishing an appropriate password-reuse policy. See Password Reuse Policy.DBA可以通过建立适当的密码重用策略来强制不重用。请参阅密码重用策略

Password Reuse Policy密码重用策略

MySQL enables restrictions to be placed on reuse of previous passwords. Reuse restrictions can be established based on number of password changes, time elapsed, or both. Reuse policy can be established globally, and individual accounts can be set to either defer to the global policy or override the global policy with specific per-account behavior.MySQL允许对重复使用以前的密码进行限制。可以根据密码更改次数、经过的时间或两者来建立重用限制。可以在全局范围内建立重用策略,并且可以将单个帐户设置为遵守全局策略或用特定的每个帐户行为覆盖全局策略。

The password history for an account consists of passwords it has been assigned in the past. MySQL can restrict new passwords from being chosen from this history:帐户的密码历史记录由过去分配的密码组成。MySQL可以限制从此历史记录中选择新密码:

  • If an account is restricted on the basis of number of password changes, a new password cannot be chosen from a specified number of the most recent passwords. 如果根据密码更改次数限制帐户,则无法从指定数量的最新密码中选择新密码。For example, if the minimum number of password changes is set to 3, a new password cannot be the same as any of the most recent 3 passwords.例如,如果密码更改的最小次数设置为3,则新密码不能与最近3个密码中的任何一个相同。

  • If an account is restricted based on time elapsed, a new password cannot be chosen from passwords in the history that are newer than a specified number of days. For example, if the password reuse interval is set to 60, a new password must not be among those previously chosen within the last 60 days.如果帐户根据经过的时间受到限制,则无法从历史记录中超过指定天数的密码中选择新密码。例如,如果密码重用间隔设置为60,则新密码不得出现在过去60天内之前选择的密码中。

Note注意

The empty password does not count in the password history and is subject to reuse at any time.空密码不计入密码历史记录,可随时重复使用。

To establish password-reuse policy globally, use the password_history and password_reuse_interval system variables.要全局建立密码重用策略,请使用password_historypassword_reuse_interval系统变量。

Examples:示例:

  • To prohibit reusing any of the last 6 passwords or passwords newer than 365 days, put these lines in the server my.cnf file:要禁止重复使用最后6个密码或超过365天的密码中的任何一个,请将以下行放入服务器my.cnf文件中:

    [mysqld]
    password_history=6
    password_reuse_interval=365
  • To set and persist the variables at runtime, use statements like this:要在运行时设置和持久化变量,请使用以下语句:

    SET PERSIST password_history = 6;
    SET PERSIST password_reuse_interval = 365;

    SET PERSIST sets the value for the running MySQL instance. SET PERSIST设置正在运行的MySQL实例的值。It also saves the value to carry over to subsequent server restarts; see Section 13.7.6.1, “SET Syntax for Variable Assignment”. 它还保存了值,以结转至后续的服务器重启;请参阅第13.7.6.1节,“变量赋值的SET语法”To change the value for the running MySQL instance without having it carry over to subsequent restarts, use the GLOBAL keyword rather than PERSIST.要更改正在运行的MySQL实例的值而不将其转移到后续重启,请使用GLOBAL关键字而不是PERSIST

The global password-reuse policy applies to all accounts that have not been set to override it. 全局密码重用策略适用于所有尚未设置为覆盖它的帐户。To establish policy for individual accounts, use the PASSWORD HISTORY and PASSWORD REUSE INTERVAL options of the CREATE USER and ALTER USER statements. 要为单个帐户建立策略,请使用CREATE USERALTER USER语句的PASSWORD HISTORYPASSWORD REUSE INTERVAL选项。See Section 13.7.1.3, “CREATE USER Statement”, and Section 13.7.1.1, “ALTER USER Statement”.请参阅第13.7.1.3节,“CREATE USER语句”第13.7.1.1节,“ALTER USER语句”

Example account-specific statements:特定账户对账单示例:

  • Require a minimum of 5 password changes before permitting reuse:在允许重新使用之前,至少需要更改5次密码:

    CREATE USER 'jeffrey'@'localhost' PASSWORD HISTORY 5;
    ALTER USER 'jeffrey'@'localhost' PASSWORD HISTORY 5;

    This history-length option overrides the global policy for all accounts named by the statement.此历史长度选项将覆盖该语句命名的所有帐户的全局策略。

  • Require a minimum of 365 days elapsed before permitting reuse:要求在允许重新使用之前至少经过365天:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;

    This time-elapsed option overrides the global policy for all accounts named by the statement.此已用时间选项将覆盖该语句命名的所有帐户的全局策略。

  • To combine both types of reuse restrictions, use PASSWORD HISTORY and PASSWORD REUSE INTERVAL together:要组合这两种类型的重用限制,请同时使用PASSWORD HISTORYPASSWORD 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;

    These options override both global policy reuse restrictions for all accounts named by the statement.这些选项覆盖了该语句命名的所有帐户的全局策略重用限制。

  • Defer to the global policy for both types of reuse restrictions:对于这两种类型的重用限制,请遵守全局策略:

    CREATE USER 'jeffrey'@'localhost'
      PASSWORD HISTORY DEFAULT
      PASSWORD REUSE INTERVAL DEFAULT;
    ALTER USER 'jeffrey'@'localhost'
      PASSWORD HISTORY DEFAULT
      PASSWORD REUSE INTERVAL DEFAULT;

Password Verification-Required Policy需要密码验证的策略

As of MySQL 8.0.13, it is possible to require that attempts to change an account password be verified by specifying the current password to be replaced. 从MySQL 8.0.13开始,可以要求通过指定要替换的当前密码来验证更改帐户密码的尝试。This enables DBAs to prevent users from changing a password without proving that they know the current password. Such changes could otherwise occur, for example, if one user walks away from a terminal session temporarily without logging out, and a malicious user uses the session to change the original user's MySQL password. This can have unfortunate consequences:这使DBA能够防止用户在没有证明他们知道当前密码的情况下更改密码。否则可能会发生此类更改,例如,如果一个用户在没有注销的情况下暂时退出终端会话,并且恶意用户使用会话更改原始用户的MySQL密码。这可能会产生不幸的后果:

  • The original user becomes unable to access MySQL until the account password is reset by an administrator.在管理员重置帐户密码之前,原始用户无法访问MySQL。

  • Until the password reset occurs, the malicious user can access MySQL with the benign user's changed credentials.在密码重置发生之前,恶意用户可以使用善意用户更改的凭据访问MySQL。

Password-verification policy can be established globally, and individual accounts can be set to either defer to the global policy or override the global policy with specific per-account behavior.密码验证策略可以全局建立,单个帐户可以设置为遵守全局策略或用特定的每个帐户行为覆盖全局策略。

For each account, its mysql.user row indicates whether there is an account-specific setting requiring verification of the current password for password change attempts. 对于每个帐户,其mysql.user行指示是否存在特定于帐户的设置,要求验证密码更改尝试的当前密码。The setting is established by the PASSWORD REQUIRE option of the CREATE USER and ALTER USER statements:该设置由CREATE USERALTER USER语句的PASSWORD REQUIRE选项建立:

  • If the account setting is PASSWORD REQUIRE CURRENT, password changes must specify the current password.如果帐户设置为PASSWORD REQUIRE CURRENT,则密码更改必须指定当前密码。

  • If the account setting is PASSWORD REQUIRE CURRENT OPTIONAL, password changes may but need not specify the current password.如果帐户设置为PASSWORD REQUIRE CURRENT OPTIONAL,则密码更改可能会但不需要指定当前密码。

  • If the account setting is PASSWORD REQUIRE CURRENT DEFAULT, the password_require_current system variable determines the verification-required policy for the account:如果帐户设置为PASSWORD REQUIRE CURRENT DEFAULT,则password_require_current系统变量将确定帐户所需的验证策略:

    • If password_require_current is enabled, password changes must specify the current password.如果启用了password_require_current,则密码更改必须指定当前密码。

    • If password_require_current is disabled, password changes may but need not specify the current password.如果禁用password_require_current,则密码更改可能会但不需要指定当前密码。

In other words, if the account setting is not PASSWORD REQUIRE CURRENT DEFAULT, the account setting takes precedence over the global policy established by the password_require_current system variable. 换句话说,如果帐户设置不是PASSWORD REQUIRE CURRENT DEFAULT,则帐户设置优先于password_require_current系统变量建立的全局策略。Otherwise, the account defers to the password_require_current setting.否则,帐户将遵循password_require_current设置。

By default, password verification is optional: password_require_current is disabled and accounts created with no PASSWORD REQUIRE option default to PASSWORD REQUIRE CURRENT DEFAULT.默认情况下,密码验证是可选的:禁用password_require_current,创建的没有PASSWORD REQUIRE选项的帐户默认为PASSWORD REQUIRE CURRENT DEFAULT

The following table shows how per-account settings interact with password_require_current system variable values to determine account password verification-required policy.下表显示了每个帐户设置如何与password_require_current系统变量值交互,以确定帐户密码验证所需的策略。

Table 6.10 Password-Verification Policy密码验证策略

Per-Account Setting每个帐户设置password_require_current System Variable系统变量Password Changes Require Current Password?密码更改需要当前密码吗?
PASSWORD REQUIRE CURRENTOFFYes
PASSWORD REQUIRE CURRENTONYes
PASSWORD REQUIRE CURRENT OPTIONALOFFNo
PASSWORD REQUIRE CURRENT OPTIONALONNo
PASSWORD REQUIRE CURRENT DEFAULTOFFNo
PASSWORD REQUIRE CURRENT DEFAULTONYes

Note注意

Privileged users can change any account password without specifying the current password, regardless of the verification-required policy. A privileged user is one who has the global CREATE USER privilege or the UPDATE privilege for the mysql system database.特权用户可以更改任何帐户密码,而无需指定当前密码,无论所需的验证策略如何。特权用户是指对mysql系统数据库具有全局CREATE USER权限或UPDATE权限的用户。

To establish password-verification policy globally, use the password_require_current system variable. Its default value is OFF, so it is not required that account password changes specify the current password.要全局建立密码验证策略,请使用password_require_current系统变量。其默认值为OFF,因此不需要帐户密码更改指定当前密码。

Examples:示例:

  • To establish a global policy that password changes must specify the current password, start the server with these lines in a server my.cnf file:要建立密码更改必须指定当前密码的全局策略,请在服务器my.cnf文件中使用以下行启动服务器:

    [mysqld]
    password_require_current=ON
  • To set and persist password_require_current at runtime, use a statement such as one of these:要在运行时设置并持久化password_require_current,请使用以下语句之一:

    SET PERSIST password_require_current = ON;
    SET PERSIST password_require_current = OFF;

    SET PERSIST sets the value for the running MySQL instance. It also saves the value to carry over to subsequent server restarts; see Section 13.7.6.1, “SET Syntax for Variable Assignment”. SET PERSIST设置正在运行的MySQL实例的值。它还保存了值,以结转至后续的服务器重启;请参阅第13.7.6.1节,“变量赋值的SET语法”To change the value for the running MySQL instance without having it carry over to subsequent restarts, use the GLOBAL keyword rather than PERSIST.要更改正在运行的MySQL实例的值而不将其转移到后续重启,请使用GLOBAL关键字而不是PERSIST

The global password verification-required policy applies to all accounts that have not been set to override it. 全局密码验证要求策略适用于所有尚未设置为覆盖它的帐户。To establish policy for individual accounts, use the PASSWORD REQUIRE options of the CREATE USER and ALTER USER statements. 要为单个帐户建立策略,请使用CREATE USERALTER USER语句的PASSWORD REQUIRE选项。See Section 13.7.1.3, “CREATE USER Statement”, and Section 13.7.1.1, “ALTER USER Statement”.请参阅第13.7.1.3节,“CREATE USER语句”第13.7.1.1节,“ALTER USER语句”

Example account-specific statements:特定账户对账单示例:

  • Require that password changes specify the current password:要求密码更改指定当前密码:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;

    This verification option overrides the global policy for all accounts named by the statement.此验证选项将覆盖该语句命名的所有帐户的全局策略。

  • Do not require that password changes specify the current password (the current password may but need not be given):不要求密码更改指定当前密码(可以但不需要提供当前密码):

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;

    This verification option overrides the global policy for all accounts named by the statement.此验证选项将覆盖该语句命名的所有帐户的全局策略。

  • Defer to the global password verification-required policy for all accounts named by the statement:遵守声明中指定的所有帐户的全局密码验证要求策略:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT DEFAULT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT DEFAULT;

Verification of the current password comes into play when a user changes a password using the ALTER USER or SET PASSWORD statement. 当用户使用ALTER USERSET PASSWORD语句更改密码时,会对当前密码进行验证。The examples use ALTER USER, which is preferred over SET PASSWORD, but the principles described here are the same for both statements.这些示例使用ALTER USER,它比SET PASSWORD更可取,但这里描述的原理对于这两个语句是相同的。

In password-change statements, a REPLACE clause specifies the current password to be replaced. Examples:在密码更改语句中,REPLACE子句指定要替换的当前密码。示例:

  • Change the current user's password:更改当前用户的密码:

    ALTER USER USER() IDENTIFIED BY 'auth_string' REPLACE 'current_auth_string';
  • Change a named user's password:更改指定用户的密码:

    ALTER USER 'jeffrey'@'localhost'
      IDENTIFIED BY 'auth_string'
      REPLACE 'current_auth_string';
  • Change a named user's authentication plugin and password:更改指定用户的身份验证插件和密码:

    ALTER USER 'jeffrey'@'localhost'
      IDENTIFIED WITH caching_sha2_password BY 'auth_string'
      REPLACE 'current_auth_string';

The REPLACE clause works like this:REPLACE子句的工作原理如下:

  • REPLACE must be given if password changes for the account are required to specify the current password, as verification that the user attempting to make the change actually knows the current password.如果需要更改帐户的密码以指定当前密码,则必须进行REPLACE,以验证试图进行更改的用户是否确实知道当前密码。

  • REPLACE is optional if password changes for the account may but need not specify the current password.如果帐户的密码更改可能但不需要指定当前密码,则REPLACE是可选的。

  • If REPLACE is specified, it must specify the correct current password, or an error occurs. This is true even if REPLACE is optional.如果指定了REPLACE,则必须指定正确的当前密码,否则会发生错误。即使REPLACE是可选的,也是如此。

  • REPLACE can be specified only when changing the account password for the current user. 只有在更改当前用户的帐户密码时才能指定REPLACE(This means that in the examples just shown, the statements that explicitly name the account for jeffrey fail unless the current user is jeffrey.) (这意味着在刚才显示的示例中,除非当前用户是jeffrey,否则显式命名jeffrey帐户的语句将失败。)This is true even if the change is attempted for another user by a privileged user; however, such a user can change any password without specifying REPLACE.即使特权用户尝试为另一个用户进行更改,这也是正确的;然而,这样的用户可以在不指定REPLACE的情况下更改任何密码。

  • REPLACE is omitted from the binary log to avoid writing cleartext passwords to it.二进制日志中省略了REPLACE,以避免向其写入明文密码。

Dual Password Support双密码支持

As of MySQL 8.0.14, user accounts are permitted to have dual passwords, designated as primary and secondary passwords. Dual-password capability makes it possible to seamlessly perform credential changes in scenarios like this:从MySQL 8.0.14开始,允许用户帐户使用双密码,指定为主密码和次密码。双密码功能使得在以下场景中无缝执行凭据更改成为可能:

  • A system has a large number of MySQL servers, possibly involving replication.一个系统有大量的MySQL服务器,可能涉及复制。

  • Multiple applications connect to different MySQL servers.多个应用程序连接到不同的MySQL服务器。

  • Periodic credential changes must be made to the account or accounts used by the applications to connect to the servers.必须对应用程序用于连接到服务器的帐户进行定期凭据更改。

Consider how a credential change must be performed in the preceding type of scenario when an account is permitted only a single password. 考虑在前一种情况下,当一个帐户只允许使用一个密码时,必须如何执行凭据更改。In this case, there must be close cooperation in the timing of when the account password change is made and propagated throughout all servers, and when all applications that use the account are updated to use the new password. 在这种情况下,在更改帐户密码并将其传播到所有服务器的时间,以及使用该帐户的所有应用程序更新为使用新密码的时间方面,必须密切合作。This process may involve downtime during which servers or applications are unavailable.此过程可能涉及服务器或应用程序不可用的停机时间。

With dual passwords, credential changes can be made more easily, in phases, without requiring close cooperation, and without downtime:使用双密码,可以更容易地分阶段更改凭据,而不需要密切合作,也不需要停机:

  1. For each affected account, establish a new primary password on the servers, retaining the current password as the secondary password. This enables servers to recognize either the primary or secondary password for each account, while applications can continue to connect to the servers using the same password as previously (which is now the secondary password).对于每个受影响的帐户,在服务器上建立一个新的主密码,保留当前密码作为辅助密码。这使服务器能够识别每个帐户的主密码或辅助密码,而应用程序可以继续使用与以前相同的密码(现在是辅助密码)连接到服务器。

  2. After the password change has propagated to all servers, modify applications that use any affected account to connect using the account primary password.在密码更改传播到所有服务器后,修改使用任何受影响帐户的应用程序,以使用帐户主密码进行连接。

  3. After all applications have been migrated from the secondary passwords to the primary passwords, the secondary passwords are no longer needed and can be discarded. 在所有应用程序从辅助密码迁移到主密码后,不再需要辅助密码,可以丢弃。After this change has propagated to all servers, only the primary password for each account can be used to connect. The credential change is now complete.此更改传播到所有服务器后,只能使用每个帐户的主密码进行连接。凭证更改现已完成。

MySQL implements dual-password capability with syntax that saves and discards secondary passwords:MySQL实现了双密码功能,其语法可以保存和丢弃辅助密码:

  • The RETAIN CURRENT PASSWORD clause for the ALTER USER and SET PASSWORD statements saves an account current password as its secondary password when you assign a new primary password.当您分配新的主密码时,ALTER USERSET PASSWORD语句的RETAIN CURRENT PASSWORD子句会将帐户当前密码保存为其辅助密码。

  • The DISCARD OLD PASSWORD clause for ALTER USER discards an account secondary password, leaving only the primary password.ALTER USERDISCARD OLD PASSWORD子句丢弃了帐户的辅助密码,只留下主密码。

Suppose that, for the previously described credential-change scenario, an account named 'appuser1'@'host1.example.com' is used by applications to connect to servers, and that the account password is to be changed from 'password_a' to 'password_b'.假设,对于前面描述的凭据更改场景,应用程序使用名为'appuser1'@'host1.example.com'的帐户连接到服务器,并且帐户密码将从'password_a'更改为'password_b'

To perform this change of credentials, use ALTER USER as follows:要执行此凭据更改,请按如下方式使用ALTER USER

  1. On each server that is not a replica, establish 'password_b' as the new appuser1 primary password, retaining the current password as the secondary password:在每台不是副本的服务器上,将'password_b'设置为新的appuser1主密码,将当前密码保留为辅助密码:

    ALTER USER 'appuser1'@'host1.example.com'
      IDENTIFIED BY 'password_b'
      RETAIN CURRENT PASSWORD;
  2. Wait for the password change to replicate throughout the system to all replicas.等待密码更改在整个系统中复制到所有副本。

  3. Modify each application that uses the appuser1 account so that it connects to the servers using a password of 'password_b' rather than 'password_a'.修改使用appuser1帐户的每个应用程序,使其使用密码'password_b'而不是'password_a'连接到服务器。

  4. At this point, the secondary password is no longer needed. On each server that is not a replica, discard the secondary password:此时,不再需要辅助密码。在每台不是副本的服务器上,丢弃辅助密码:

    ALTER USER 'appuser1'@'host1.example.com'
      DISCARD OLD PASSWORD;
  5. After the discard-password change has replicated to all replicas, the credential change is complete.丢弃密码更改复制到所有副本后,凭据更改完成。

The RETAIN CURRENT PASSWORD and DISCARD OLD PASSWORD clauses have the following effects:RETAIN CURRENT PASSWORD(保留当前密码)和DISCARD OLD PASSWORD(放弃旧密码)子句具有以下效力:

  • RETAIN CURRENT PASSWORD retains an account current password as its secondary password, replacing any existing secondary password. RETAIN CURRENT PASSWORD保留帐户当前密码作为其辅助密码,替换任何现有的辅助密码。The new password becomes the primary password, but clients can use the account to connect to the server using either the primary or secondary password. 新密码将成为主密码,但客户端可以使用该帐户使用主密码或辅助密码连接到服务器。(Exception: If the new password specified by the ALTER USER or SET PASSWORD statement is empty, the secondary password becomes empty as well, even if RETAIN CURRENT PASSWORD is given.)(例外:如果ALTER USERSET PASSWORD语句指定的新密码为空,则即使给出了RETAIN CURRENT PASSWORD,辅助密码也会变为空。)

  • If you specify RETAIN CURRENT PASSWORD for an account that has an empty primary password, the statement fails.如果为主密码为空的帐户指定RETAIN CURRENT PASSWORD,则语句将失败。

  • If an account has a secondary password and you change its primary password without specifying RETAIN CURRENT PASSWORD, the secondary password remains unchanged.如果一个帐户有辅助密码,而您在没有指定RETAIN CURRENT PASSWORD的情况下更改了其主密码,则辅助密码保持不变。

  • For ALTER USER, if you change the authentication plugin assigned to the account, the secondary password is discarded. 对于ALTER USER,如果更改分配给帐户的身份验证插件,则会丢弃辅助密码。If you change the authentication plugin and also specify RETAIN CURRENT PASSWORD, the statement fails.如果更改身份验证插件并指定RETAIN CURRENT PASSWORD,则语句将失败。

  • For ALTER USER, DISCARD OLD PASSWORD discards the secondary password, if one exists. 对于ALTER USERDISCARD OLD PASSWORD会丢弃辅助密码(如果存在)。The account retains only its primary password, and clients can use the account to connect to the server only with the primary password.该帐户仅保留其主密码,客户端只能使用该帐户使用主密码连接到服务器。

Statements that modify secondary passwords require these privileges:修改辅助密码的语句需要以下权限:

  • The APPLICATION_PASSWORD_ADMIN privilege is required to use the RETAIN CURRENT PASSWORD or DISCARD OLD PASSWORD clause for ALTER USER and SET PASSWORD statements that apply to your own account. 对于适用于您自己帐户的ALTER USERSET PASSWORD语句,需要APPLICATION_PASSWORD_ADMIN权限才能使用RETAIN CURRENT PASSWORDDISCARD OLD PASSWORD子句。The privilege is required to manipulate your own secondary password because most users require only one password.操作您自己的辅助密码需要权限,因为大多数用户只需要一个密码。

  • If an account is to be permitted to manipulate secondary passwords for all accounts, it should be granted the CREATE USER privilege rather than APPLICATION_PASSWORD_ADMIN.如果允许一个帐户操作所有帐户的辅助密码,则应授予其CREATE USER权限,而不是APPLICATION_PASSWORD_ADMIN

Random Password Generation随机密码生成

As of MySQL 8.0.18, the CREATE USER, ALTER USER, and SET PASSWORD statements have the capability of generating random passwords for user accounts, as an alternative to requiring explicit administrator-specified literal passwords. 从MySQL 8.0.18开始,CREATE USERALTER USERSET PASSWORD语句能够为用户帐户生成随机密码,作为要求管理员明确指定文字密码的替代方案。See the description of each statement for details about the syntax. This section describes the characteristics common to generated random passwords.有关语法的详细信息,请参阅每个语句的描述。本节描述了生成的随机密码的共同特征。

By default, generated random passwords have a length of 20 characters. 默认情况下,生成的随机密码长度为20个字符。This length is controlled by the generated_random_password_length system variable, which has a range from 5 to 255.该长度由generated_random_password_length系统变量控制,其范围为5到255。

For each account for which a statement generates a random password, the statement stores the password in the mysql.user system table, hashed appropriately for the account authentication plugin. 对于每个由语句生成随机密码的帐户,该语句将密码存储在mysql.user系统表中,并针对帐户身份验证插件进行适当的哈希处理。The statement also returns the cleartext password in a row of a result set to make it available to the user or application executing the statement. 该语句还在结果集的一行中返回明文密码,以便执行该语句的用户或应用程序可以使用。The result set columns are named user, host, and generated password, indicating the user name and host name values that identify the affected row in the mysql.user system table, and the cleartext generated password.结果集列分别命名为userhostgenerated password,表示标识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   |
+------+---------------+----------------------+
| u1   | localhost     | BA;42VpXqQ@i+y{&TDFF |
| u2   | %.example.com | YX5>XRAJRP@>sn9azmD4 |
| u3   | %.org         | ;GfD44l,)C}PI/6)4TwZ |
+------+---------------+----------------------+
mysql> ALTER USER
'u1'@'localhost' IDENTIFIED BY RANDOM PASSWORD,
'u2'@'%.example.com' IDENTIFIED BY RANDOM PASSWORD;
+------+---------------+----------------------+
| user | host          | generated password   |
+------+---------------+----------------------+
| u1   | localhost     | yhXBrBp.;Y6abB)e_UWr |
| u2   | %.example.com | >M-vmjp9DTY6}hkp,RcC |
+------+---------------+----------------------+
mysql> SET PASSWORD FOR 'u3'@'%.org' TO RANDOM;
+------+-------+----------------------+
| user | host  | generated password   |
+------+-------+----------------------+
| u3   | %.org | o(._oNn)d;FC<vJIDg9M |
+------+-------+----------------------+

A CREATE USER, ALTER USER, or SET PASSWORD statement that generates a random password for an account is written to the binary log as a CREATE USER or ALTER USER statement with an IDENTIFIED WITH auth_plugin AS 'auth_string', clause, where auth_plugin is the account authentication plugin and 'auth_string' is the account hashed password value.为帐户生成随机密码的CREATE USERALTER USERSET PASSWORD语句将作为CREATE USERALTER USER语句写入二进制日志,并带有IDENTIFIED WITH auth_plugin AS 'auth_string'子句,其中auth_plugin是帐户身份验证插件,'auth_string'是帐户哈希密码值。

If the validate_password component is installed, the policy that it implements has no effect on generated passwords. 如果安装了validate_password组件,则它实现的策略对生成的密码没有影响。(The purpose of password validation is to help humans create better passwords.)(密码验证的目的是帮助人类创建更好的密码。)

Failed-Login Tracking and Temporary Account Locking登录跟踪和临时帐户锁定失败

As of MySQL 8.0.19, administrators can configure user accounts such that too many consecutive login failures cause temporary account locking.从MySQL 8.0.19开始,管理员可以配置用户帐户,这样连续登录失败次数过多会导致临时帐户锁定。

Login failure in this context means failure of the client to provide a correct password during a connection attempt. It does not include failure to connect for reasons such as unknown user or network issues. 在此上下文中,“登录失败”是指客户端在连接尝试期间未能提供正确的密码。它不包括因未知用户或网络问题等原因导致的连接失败。For accounts that have dual passwords (see Dual Password Support), either account password counts as correct.对于具有双密码的帐户(请参阅双密码支持),任何帐户密码都视为正确。

The required number of login failures and the lock time are configurable per account, using the FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME options of the CREATE USER and ALTER USER statements. 使用CREATE USERALTER USER语句的FAILED_LOGIN_ATTEMPTSPASSWORD_LOCK_TIME选项,可以为每个帐户配置所需的登录失败次数和锁定时间。Examples:示例:

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;

When too many consecutive login failures occur, the client receives an error that looks like this:当连续发生太多登录失败时,客户端会收到一个如下所示的错误:

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.

Use the options as follows:使用以下选项:

  • FAILED_LOGIN_ATTEMPTS N

    This option indicates whether to track account login attempts that specify an incorrect password. 此选项指示是否跟踪指定错误密码的帐户登录尝试。The number N specifies how many consecutive incorrect passwords cause temporary account locking.数字N指定有多少连续的错误密码导致临时帐户锁定。

  • PASSWORD_LOCK_TIME {N | UNBOUNDED}

    This option indicates how long to lock the account after too many consecutive login attempts provide an incorrect password. 此选项指示在连续多次登录尝试提供错误密码后锁定帐户的时间。The value is a number N to specify the number of days the account remains locked, or UNBOUNDED to specify that when an account enters the temporarily locked state, the duration of that state is unbounded and does not end until the account is unlocked. 该值是一个数字N,用于指定帐户保持锁定的天数,或是UNBOUNDED,用于指定当帐户进入临时锁定状态时,该状态的持续时间是无限制的,并且在帐户解锁之前不会结束。The conditions under which unlocking occurs are described later.稍后将描述解锁发生的条件。

Permitted values of N for each option are in the range from 0 to 32767. A value of 0 disables the option.每个选项的N允许值在0到32767的范围内。值为0时禁用该选项。

Failed-login tracking and temporary account locking have these characteristics:登录跟踪失败和临时帐户锁定具有以下特征:

  • For failed-login tracking and temporary locking to occur for an account, its FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME options both must be nonzero.为了使帐户发生登录跟踪失败和临时锁定,其FAILED_LOGIN_ATTEMPTSPASSWORD_LOCK_TIME选项都必须为非零。

  • For CREATE USER, if FAILED_LOGIN_ATTEMPTS or PASSWORD_LOCK_TIME is not specified, its implicit default value is 0 for all accounts named by the statement. 对于CREATE USER,如果未指定FAILED_LOGIN_ATTEMPTSPASSWORD_LOCK_TIME,则该语句命名的所有帐户的隐式默认值为0。This means that failed-login tracking and temporary account locking are disabled. (These implicit defaults also apply to accounts created prior to the introduction of failed-login tracking.)这意味着已禁用失败的登录跟踪和临时帐户锁定。(这些隐式默认值也适用于在引入失败登录跟踪之前创建的帐户。)

  • For ALTER USER, if FAILED_LOGIN_ATTEMPTS or PASSWORD_LOCK_TIME is not specified, its value remains unchanged for all accounts named by the statement.对于ALTER USER,如果未指定FAILED_LOGIN_ATTEMPTSPASSWORD_LOCK_TIME,则其值对于该语句命名的所有帐户保持不变。

  • For temporary account locking to occur, password failures must be consecutive. 为了发生临时帐户锁定,密码失败必须是连续的。Any successful login that occurs prior to reaching the FAILED_LOGIN_ATTEMPTS value for failed logins causes failure counting to reset. 在达到失败登录的FAILED_LOGIN_ATTEMPTS值之前发生的任何成功登录都会导致失败计数重置。For example, if FAILED_LOGIN_ATTEMPTS is 4 and three consecutive password failures have occurred, one more failure is necessary for locking to begin. 例如,如果FAILED_LOGIN_ATTEMPTS为4,并且连续发生了三次密码失败,则需要再发生一次失败才能开始锁定。But if the next login succeeds, failed-login counting for the account is reset so that four consecutive failures are again required for locking.但是,如果下一次登录成功,则重置帐户的登录失败计数,因此需要再次连续四次失败才能锁定。

  • Once temporary locking begins, successful login cannot occur even with the correct password until either the lock duration has passed or the account is unlocked by one of the account-reset methods listed in the following discussion.一旦临时锁定开始,即使使用正确的密码,也无法成功登录,直到锁定持续时间过去或帐户通过以下讨论中列出的帐户重置方法之一解锁。

When the server reads the grant tables, it initializes state information for each account regarding whether failed-login tracking is enabled, whether the account is currently temporarily locked and when locking began if so, and the number of failures before temporary locking occurs if the account is not locked.当服务器读取授权表时,它会初始化每个帐户的状态信息,包括是否启用了失败的登录跟踪、帐户当前是否被临时锁定以及锁定开始的时间(如果是),以及如果帐户未被锁定,在临时锁定发生之前的失败次数。

An account's state information can be reset, which means that failed-login counting is reset, and the account is unlocked if currently temporarily locked. Account resets can be global for all accounts or per account:帐户的状态信息可以重置,这意味着登录失败计数将重置,如果当前临时锁定,则帐户将解锁。帐户重置可以是所有帐户的全局重置,也可以是每个帐户的重置:

  • A global reset of all accounts occurs for any of these conditions:以下任何一种情况都会对所有帐户进行全局重置:

    • A server restart.服务器重新启动。

    • Execution of FLUSH PRIVILEGES. 执行FLUSH PRIVILEGES(Starting the server with --skip-grant-tables causes the grant tables not to be read, which disables failed-login tracking. (使用--skip-grant-tables启动服务器会导致无法读取授权表,从而禁用失败的登录跟踪。In this case, the first execution of FLUSH PRIVILEGES causes the server to read the grant tables and enable failed-login tracking, in addition to resetting all accounts.)在这种情况下,除了重置所有帐户外,首次执行FLUSH PRIVILES还会导致服务器读取授权表并启用失败的登录跟踪。)

  • A per-account reset occurs for any of these conditions:以下任何一种情况都会发生每个帐户重置:

    • Sucessful login for the account.帐户登录成功。

    • The lock duration passes. In this case, failed-login counting resets at the time of the next login attempt.锁定时间已过。在这种情况下,失败的登录计数将在下次登录尝试时重置。

    • Execution of an ALTER USER statement for the account that sets either FAILED_LOGIN_ATTEMPTS or PASSWORD_LOCK_TIME (or both) to any value (including the current option value), or execution of an ALTER USER ... UNLOCK statement for the account.为帐户执行ALTER USER语句,将FAILED_LOGIN_ATTEMPTSPASSWORD_LOCK_TIME(或两者)设置为任何值(包括当前选项值),或对账户执行ALTER USER ... UNLOCK子句。

      Other ALTER USER statements for the account have no effect on its current failed-login count or its locking state.该帐户的其他ALTER USER语句对其当前的登录失败计数或锁定状态没有影响。

Failed-login tracking is tied to the login account that is used to check credentials. 失败的登录跟踪与用于检查凭据的登录帐户相关联。If user proxying is in use, tracking occurs for the proxy user, not the proxied user. 如果正在使用用户代理,则会对代理用户而不是被代理的用户进行跟踪。That is, tracking is tied to the account indicated by USER(), not the account indicated by CURRENT_USER(). 也就是说,跟踪与USER()指示的帐户相关联,而不是与CURRENT_USER()所指示的帐户相关。For information about the distinction between proxy and proxied users, see Section 6.2.18, “Proxy Users”.有关代理和被代理用户之间区别的信息,请参阅第6.2.18节,“代理用户”