-
MYSQL 8.0之密码管理(2)
- 1
- 2
- 3
- 4
- 5
- 6
密码验证要求策略
从MySQL 8.0.13开始,可能需要通过指定要替换的当前密码来验证更改帐户密码的尝试。这使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
系统变量值进行交互,以确定需要帐户密码验证的策略。
密码验证策略
每个账户的设置 | password_require_current 系统变量 | 修改密码前是否需要确认原密码 |
---|---|---|
PASSWORD REQUIRE CURRENT |
OFF |
Yes |
PASSWORD REQUIRE CURRENT |
ON |
Yes |
PASSWORD REQUIRE CURRENT OPTIONAL |
OFF |
No |
PASSWORD REQUIRE CURRENT OPTIONAL |
ON |
No |
PASSWORD REQUIRE CURRENT DEFAULT |
OFF |
No |
PASSWORD REQUIRE CURRENT DEFAULT |
ON |
Yes |
注意 特权用户可以在不指定当前密码的情况下更改任何帐户密码,而不管验证要求的策略如何。特权用户是具有
mysql
系统数据库的全局CREATE USER
特权或UPDATE
特权的用户。
要全局建立密码验证策略,请使用password_require_current
系统变量。其默认值为OFF
,因此不需要更改帐户密码来指定当前密码。 示例:
-
要建立密码更改必须指定当前密码的全局策略,请在服务器
my.cnf
文件中使用以下几行启动服务器:- 1
- 2
-
要在运行时设置和保留
password_require_current
,请使用以下语句之一:- 1
- 2
SET PERSIST设置正在运行的MySQL实例的值。它还保存该值以继续进行后续服务器重新启动。要更改正在运行的MySQL实例的值而不使它继续进行后续的重新启动,请使用
GLOBAL
关键字而不是PERSIST
。
要求全局密码验证的策略适用于尚未设置为覆盖该策略的所有帐户。要为单个帐户建立策略,请使用CREATE USER
和ALTER USER
语句的PASSWORD REQUIRE
选项。
一个对账单示例
-
要求密码更改指定当前密码:
- 1
- 2
该验证选项将覆盖该语句命名的所有帐户的全局策略。
-
不需要更改密码指定当前密码(可以但不必提供当前密码):
- 1
- 2
当用户使用
ALTER USER
或SET PASSWORD
语句更改密码时,对当前密码进行验证。这些示例使用ALTER USER
,这比SET PASSWORD
更为可取,但是这里描述的原理对于两个语句都是相同的。 -
对语句命名的所有帐户都遵循全局密码验证所需的策略:
- 1
- 2
当用户使用ALTER USER
或SET PASSWORD
语句更改密码时,对当前密码进行验证。这些示例使用ALTER USER
,这比SET PASSWORD
更为可取,但是这里描述的原理对于两个语句都是相同的。
在更改密码的语句中,REPLACE
子句指定要替换的当前密码。
示例:
-
更改当前用户的密码:
- 1
-
更改指定用户的密码:
- 1
- 2
- 3
-
更改命名用户的身份验证插件和密码:
- 1
- 2
- 3
REPLACE
子句的工作方式如下:
-
如果需要更改帐户密码以指定当前密码,则必须给出
REPLACE
,以验证尝试进行更改的用户实际上知道当前密码。 -
如果可以(但不必指定当前密码)更改帐户密码,则
REPLACE
是可选的。 -
如果指定了
REPLACE
,则必须指定正确的当前密码,否则会发生错误。 -
即使
REPLACE
是可选的,也是如此。 -
仅当更改当前用户的帐户密码时才能指定
REPLACE
。(这意味着在刚刚显示的示例中,除非当前用户为jeffrey
,否则显式命名jeffrey
帐户的语句将失败。)即使特权用户尝试对另一个用户进行更改,也是如此。但是,这样的用户可以在不指定REPLACE
的情况下更改任何密码。 -
二进制日志中省略了
REPLACE
,以避免向其写入明文密码。
双密码支持
从MySQL 8.0.14开始,允许用户帐户具有双重密码,分别指定为主要和次要密码。双密码功能使在以下情况下无缝执行凭据更改成为可能:
- 系统具有大量的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
主密码,并保留当前密码作为辅助密码:- 1
- 2
- 3
-
等待密码更改,以将整个系统复制到所有从属服务器。
-
修改使用
appuser1
帐户的每个应用程序,以使其使用password_b
而不是password_a
的密码连接到服务器。 -
此时,不再需要辅助密码。在不是复制从服务器的每个服务器上,放弃辅助密码: