Documentation Home
MySQL 8.0 参考手册  / 第 6 章 安全  / 6.2 访问控制和账户管理  /  6.2.12 服务器对过期密码的处理

6.2.12 服务器对过期密码的处理

MySQL 提供密码过期功能,使数据库管理员能够要求用户重置密码。密码可以手动过期,也可以根据自动过期策略(请参阅 第 6.2.11 节,“密码管理”)。

ALTER USER语句启用帐户密码过期。例如:

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

对于使用密码过期帐户的每个连接,服务器要么断开客户端连接,要么将客户端限制为沙盒模式,在该模式下,服务器只允许客户端执行重置过期密码所需的操作。服务器采取何种操作取决于客户端和服务器设置,如后所述。

如果服务器断开客户端连接,它会返回一个 ER_MUST_CHANGE_PASSWORD_LOGIN 错误:

$> mysql -u myuser -p
Password: ******
ERROR 1862 (HY000): Your password has expired. To log in you must
change it using a client that supports expired passwords.

如果服务器将客户端限制为沙盒模式,则在客户端会话中允许执行以下操作:

  • ALTER USER客户端可以使用或 重置账户密码 SET PASSWORD。完成后,服务器恢复会话的正常访问,以及使用该帐户的后续连接。

    笔记

    虽然可以通过将过期的密码设置为当前值来重置该密码,但作为一种好的策略,最好选择一个不同的密码。

  • 客户端可以使用 SET mysql 5.7.6 之前有用的语句 if SET PASSWORDmust be used instead ALTER USERand the account uses a authentication plugin for which the old_passwordssystem variable must be first be set to a nondefault value to perform password hashing in a specific way.

对于会话中不允许的任何操作,服务器返回ER_MUST_CHANGE_PASSWORD 错误:

mysql> USE performance_schema;
ERROR 1820 (HY000): You must reset your password using ALTER USER
statement before executing this statement.

mysql> SELECT 1;
ERROR 1820 (HY000): You must reset your password using ALTER USER
statement before executing this statement.

这是 mysql客户端的交互式调用通常发生的情况,因为默认情况下此类调用处于沙盒模式。要恢复正常功能,请选择一个新密码。

对于mysql 客户端的非交互式调用(例如,在批处理模式下),如果密码过期,服务器通常会断开客户端连接。要允许非交互式mysql调用保持连接以便可以更改密码(使用沙盒模式中允许的语句),请将 --connect-expired-password选项添加到mysql命令。

如前所述,服务器是断开密码过期客户端的连接还是将其限制为沙盒模式取决于客户端和服务器设置的组合。以下讨论描述了相关设置以及它们如何交互。

笔记

此讨论仅适用于密码过期的帐户。如果客户端使用未过期的密码进行连接,则服务器会正​​常处理客户端。

在客户端,给定的客户端指示它是否可以处理过期密码的沙箱模式。对于使用 C 客户端库的客户端,有两种方法可以做到这一点:

  • 在连接之前 将MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS标志 传递 给:mysql_options()

    my_bool arg = 1;
    mysql_options(mysql,
                  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
                  &arg);

    这是在mysql 客户端中 使用的技术,MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS如果以交互方式调用或使用 --connect-expired-password 选项,则启用该技术。

  • 在连接时 将CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS标志 传递 给:mysql_real_connect()

    MYSQL mysql;
    mysql_init(&mysql);
    if (!mysql_real_connect(&mysql,
                            host, user, password, db,
                            port, unix_socket,
                            CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS))
    {
      ... handle error ...
    }

Other MySQL Connectors have their own conventions for indicating readiness to handle sandbox mode. See the documentation for the Connector in which you are interested.

On the server side, if a client indicates that it can handle expired passwords, the server puts it in sandbox mode.

If a client does not indicate that it can handle expired passwords (or uses an older version of the client library that cannot so indicate), the server action depends on the value of the disconnect_on_expired_password system variable: