mysql中GRANT与REVOKE语句的使用与权限管理

4次阅读

GRANT语句需满足执行者有GRANT OPTION权限且目标用户已存在;正确写法如GRANT select,INSERT ON app_db.* TO ‘app_user’@’10.20.%’;REVOKE后需FLUSH PRIVILEGES生效;mysql 8.0角色权限不自动转授,须显式加WITH ADMIN OPTION;生产环境应禁用FILE、PROCESS、SUPER等高危权限。

mysql中GRANT与REVOKE语句的使用与权限管理

GRANT 语句怎么写才不会报错 access denied 或 Illegal GRANT

MySQL 的 GRANT 不是“给权限就完事”,它依赖两个前提:执行者本身有 GRANT OPTION 权限,且目标用户('user'@'host')在 mysql.user 表中已存在(或能被自动创建)。常见错误包括:

  • 用普通账号执行 GRANT —— 报错 Access denied; you need (at least one of) the GRANT OPTION privilege(s)
  • 漏写主机名,比如只写 'myuser' 而不是 'myuser'@'localhost' —— MySQL 会按 'myuser'@'%' 匹配,可能授错对象
  • 对不存在的数据库/表授予权限(如 GRANT SELECT ON nonexistent_db.* TO ...)—— 语句能执行,但后续访问仍报 table doesn't exist,容易误判为权限问题

正确写法示例(以 root 登录后):

GRANT SELECT, INSERT ON `app_db`.* TO 'app_user'@'10.20.%' IDENTIFIED BY 'strong_pass_2024';

注意:IDENTIFIED BY 在 MySQL 8.0+ 中不推荐用于已有用户(应改用 ALTER USER),仅首次创建时可用;若用户已存在,去掉该子句。

REVOKE 删除权限后为什么 SHOW GRANTS 还显示旧权限

REVOKE 执行成功不代表权限立即失效,因为 MySQL 权限缓存未刷新。用户当前连接仍保留旧权限,新连接才会生效。更关键的是:如果权限是通过不同 host 条目授予的(比如 'user'@'localhost''user'@'127.0.0.1'),REVOKE 只影响显式指定的那一行,其余 host 条目不受影响。

  • 执行 REVOKE SELECT ON app_db.* FROM 'app_user'@'10.20.%'; 后,立刻查 SHOW GRANTS for 'app_user'@'10.20.%'; 会更新,但 SHOW GRANTS FOR 'app_user'@'%'; 可能还有其它权限
  • 必须手动运行 FLUSH PRIVILEGES; 才能让所有连接感知变更(虽然多数情况下 MySQL 自动重载,但高并发或复制环境建议显式执行)
  • 撤销所有权限的简写是 REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'host';,注意它不删除用户,只清空权限

MySQL 8.0 权限模型变化:ROLE 与 WITH GRANT OPTION 的区别

MySQL 8.0 引入角色(CREATE ROLE),但角色权限和直接授权行为不等价。核心差异在于:WITH GRANT OPTION 允许被授权者再转授,而角色不能直接转授(需显式 GRANT ROLE ... TO ... WITH ADMIN OPTION)。

  • 老写法:GRANT SELECT ON sales.* TO 'analyst'@'%' WITH GRANT OPTION; → analyst 可再执行 GRANT SELECT ON sales.* TO 'intern'@'%';
  • 角色写法:CREATE ROLE 'sales_reader'; GRANT SELECT ON sales.* TO 'sales_reader'; GRANT 'sales_reader' TO 'analyst'@'%'; → analyst 默认无法把 sales_reader 授给别人,除非加 WITH ADMIN OPTION
  • 权限继承是静态的:用户被授予角色后,角色权限变更会自动同步;但若用户已有直接权限,角色权限不会覆盖它

所以不要以为建了 role 就一劳永逸——SHOW GRANTS 会同时列出直接权限和角色权限,排查时得两头看。

最小权限原则落地:哪些权限其实不该轻易给

生产环境最常被过度授予、又最容易引发事故的权限有三个:FILEPROCESSSUPER。它们不属于数据库对象操作,而是服务器级控制权。

  • FILE:允许用户读写服务器任意文件(LOAD DATA INFILE / SELECT ... INTO OUTFILE),一旦 Web 应用存在 SQL 注入,攻击者可直接读取 /etc/passwd 或写入 Webshell
  • PROCESS:能看到所有连接的完整 SQL(含密码明文),SHOW PROCEsslIST 输出敏感信息
  • SUPER:可 kill 任意线程、修改全局变量(如关掉 sql_log_bin 绕过 binlog)、甚至切换主从复制状态 —— 运维账号才应持有

真正业务账号,通常只需:SELECTINSERTUPDATEdelete(按需限制库/表),外加 EXECUTE(调用存储过程)和 SHOW VIEW(查视图)。连 CREATE 都该由 dba 统一管理。

text=ZqhQzanResources