MySQL不提供禁止用户改密的权限开关,真正有效的是回收CREATE USER和UPDATE ON mysql.user权限,并可配合ACCOUNT LOCK彻底禁用账户;validate_password插件仅校验新密码强度,不禁止操作。

MySQL 本身不提供禁止用户修改自己密码的权限开关,ALTER USER 是用户级操作,只要用户拥有 CREATE USER、UPDATE 权限(或更高),就能执行 ALTER USER ... IDENTIFIED BY。真正能“拦住”密码修改的,只有 validate_password 插件——它不禁止操作,只在校验新密码时抛错。
为什么 REVOKE ALTER USER 没用
MySQL 没有 ALTER USER 这个独立权限项。所谓“能改密码”,本质是用户拥有以下任一能力:
- 被显式授予
CREATE USER权限(该权限隐含修改自身认证信息的能力) - 拥有全局
UPDATE权限(可直写mysql.user表的authentication_string字段) - 通过角色继承了上述权限(MySQL 8.0+ 常见)
执行 REVOKE ALTER USER ON *.* FROM 'u'@'h' 会报错:语法不合法,因为 ALTER USER 不是标准权限名。你查 SHOW GRANTS FOR 'u'@'h',也找不到这一行。
真正有效的拦截方式:禁用 CREATE USER + 锁定账户
想让普通用户彻底无法改密,得从能力源头掐断。最可靠组合是:
- 撤掉
CREATE USER权限:REVOKE CREATE USER ON *.* FROM 'u'@'h' - 确认没残留
UPDATE权限:REVOKE UPDATE ON mysql.user FROM 'u'@'h'(注意:必须指定mysql.user,不能写*.*) - 额外加固:用
ALTER USER 'u'@'h' ACCOUNT LOCK直接禁用登录(比改密码更彻底)
注意:如果用户已通过角色获得 CREATE USER,仅对用户本体 REVOKE 无效,必须查 mysql.role_edges 并对对应角色也撤销。
validate_password 插件不是“禁止”,而是“强制强度”
很多人误以为调低 validate_password_policy 就能放开改密限制,其实它只影响新密码是否被接受:
- 策略为
MEDIUM时,'123456'会被拒绝,报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements - 设成
LOW后仍需同步调validate_password_length = 6,否则默认仍要求 8 位 - 插件对已存在的弱密码完全无感——它只在
ALTER USER、SET PASSWORD、CREATE USER时触发校验
所以插件适合做“安全兜底”,不能替代权限回收。一旦用户绕过校验(比如用哈希值直写字段),插件就失效了。
回收后务必验证是否真生效
REVOKE 命令不校验目标用户是否存在,也不检查该用户是否真有你要撤的权限。看似 Query OK,可能根本没作用。验证方法只有两个:
- 重连后执行
SHOW GRANTS FOR 'u'@'h',确认输出里已无CREATE USER或UPDATE ON mysql.user - 用该用户连接,尝试
ALTER USER USER() IDENTIFIED BY 'x',看是否报ERROR 1045 (28000): Access denied
最容易被忽略的是角色继承和 GRANT OPTION:哪怕你 revoke 了用户本体权限,只要其某个角色仍有 CREATE USER,或者曾被授过 WITH GRANT OPTION,权限就还在。


















