mysql如何配置只读用户_mysql最小权限应用示例

7次阅读

mysql只读用户只需授予select权限,必要时加SHOW CREATE table或PROCESS(慎用),严禁GRANT SELECT ON .,须限定库、主机并验证无其他权限。

mysql如何配置只读用户_mysql最小权限应用示例

只读用户必须授予哪些权限

MySQL 的只读访问不是靠一个 READ ONLY 权限实现的,而是通过显式授予有限的、不带写能力的权限组合。核心是:只给 SELECT,不给 INSERTUPDATEdeleteDROPCREATEALTER 等任何修改类权限。

常见错误是误加 SHOW VIEWLOCK TABLES——它们虽不直接写数据,但可能暴露结构或阻塞业务,生产环境应按需开启。

  • SELECT 是唯一必需的基础权限
  • 如需查看表结构,额外加 SHOW CREATE TABLE(注意:不是 SHOW databaseS
  • 如需执行 EXPLaiN 或查看执行计划,需 PROCESS 权限(仅限本地调试,线上慎开)
  • 跨库 JOIN 查询时,目标库所有涉及的表都要单独授权 SELECT

创建最小权限只读用户的完整命令

假设数据库名为 app_db,用户名为 ro_user,密码为 'secure_ro_pass',只允许从内网 192.168.10.% 连接:

CREATE USER 'ro_user'@'192.168.10.%' IDENTIFIED BY 'secure_ro_pass'; GRANT SELECT ON app_db.* TO 'ro_user'@'192.168.10.%'; FLUSH PRIVILEGES;

关键点:

  • 不要用 GRANT SELECT ON *.* —— 这会暴露系统库(如 information_schema),存在信息泄露风险
  • 主机名尽量具体,避免用 '%';若必须通配,请确认网络层已限制访问源
  • FLUSH PRIVILEGES 在大多数情况下非必需(只要用 GRANT 语句就自动生效),但部分旧版本或特殊部署下建议保留

验证只读权限是否生效

用新用户登录后,执行以下检查:

  • 能成功运行 SELECT count(*) FROM app_db.users;
  • 执行 INSERT INTO app_db.users (...) VALUES (...); 应报错:Error 1142 (42000): INSERT command denied to user
  • 执行 SHOW GRANTS FOR CURRENT_USER; 确认返回结果中只有 SELECT 权限,无其他 DML/DCL 权限
  • 尝试 USE mysql; 后查 user 表——应因无权限拒绝,而非返回空结果(空结果说明有权限但没数据,是严重误配置)

应用连接池中要注意的兼容性问题

某些 ORM 或连接池(如 HikariCP、Druid)在初始化时会默认执行 SELECT 1SELECT @@sql_mode 等探测语句。这些语句本身没问题,但若连接字符串中指定了 database=xxx 而该库未被授权,就会连接失败。

解决方案:

  • 确保 GRANT SELECT ON .* 中的库名与应用配置完全一致(大小写敏感取决于 OS 和 lower_case_table_names 设置)
  • 避免在 JDBC URL 中指定不存在或未授权的 database 参数;可改用 usessl=false&serverTimezone=UTC 等纯连接参数
  • spring Boot + mybatis 场景下,spring.sql.init.mode=never 必须显式设置,否则启动时可能尝试建表

最易忽略的是:MySQL 8.0+ 默认启用 caching_sha2_password 插件,而旧版客户端可能不支持——此时即使权限正确,也会卡在认证阶段,报错类似 public Key Retrieval is not allowed。需确认客户端驱动版本或改用 mysql_native_password 认证方式。

text=ZqhQzanResources