MySQL权限管理的坑你踩了没有?

假设有这么一个需求,开发人员要求你创建一个账号test,要求这个账号有创建表,查询,更新,删除表的权限, 如下例子所示

/* by yours.tools - online tools website : yours.tools/zh/caiji.html */
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.4.5     |
+-----------+
1 row in set (0.00 sec)

mysql> create database if not exists kerry   
    -> default character set utf8mb4
    -> default collate utf8mb4_general_ci;
query ok, 1 row affected (0.02 sec)


mysql> create user `test`@`%` identified by  'Test@#$123456';
Query OK, 0 rows affected (0.02 sec)

mysql> 

mysql> grant create, drop ,select,update on kerry.* to test@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

mysql>

然后我们以test用户登录数据库, 此时你执行下面SQL,你会发现,你不光有drop掉表的权限,甚至连数据库kerry都可以drop掉.如下所示

/* by yours.tools - online tools website : yours.tools/zh/caiji.html */
mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| test@%         |
+----------------+
1 row in set (0.00 sec)

mysql> create table t1(id int, name varchar(12));
Query OK, 0 rows affected (0.02 sec)

mysql> drop table t1;
Query OK, 0 rows affected (0.01 sec)

mysql> drop database kerry;
Query OK, 0 rows affected (0.01 sec)

mysql> 

然后你会发现,test用户不光有drop掉数据库kerry的权限,而且有创建数据库kerry的权限(仅仅是创建/删除kerry这个数据库.没有创建/删除其它数据库的权限),如下所示:

mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| test@%         |
+----------------+
1 row in set (0.00 sec)

mysql> create database if not exists kerry
    -> default character set utf8mb4
    -> default collate utf8mb4_general_ci;
query ok, 1 row affected (0.01 sec)

mysql> drop database kerry;
query ok, 0 rows affected (0.00 sec)

mysql> create database kkk;
error 1044 (42000): access denied for user 'test'@'%' to database 'kkk' 

mysql> drop database k2;
ERROR 1044 (42000): Access denied for user 'test'@'%' to database 'k2'
mysql>

其实具体原因是你没有留意MySQL官方文档关于CREATE/DROP权限的详细说明,你以为的CREATE权限是创建表的权限,DROP权限是DROP表的权限.其实不然, 如下截图所示,CREATE权限包含创建数据库、表或索引的权限,而DROP权限包DROP数据库、表或视图的权限. 至于为什么MySQL没有细化这些权限.我们也不清楚.但是从上面实验来看, 我都倾向于这个是一个逻辑上的"Bug".

那么如果这样授权,会有什么问题呢? **如果账号授予了DROP权限,那么这就是一个安全权限的"漏洞", SQL注入式攻击都可以利用这个"漏洞"直接将数据库给删除了. **

解决方案

MySQL中没有单独的CREATE TABLE, DROP TABLE的权限,我们只能另避蹊径,先收回账号test的DROP权限,然后创建一个角色drop_tab,这个角色授予数据库kerry中具体每一个表的DROP权限,最后授予用户这个角色. 如下所示:

mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.01 sec)

mysql> show grants for test@'%';
+---------------------------------------------------------------+
| Grants for test@%                                             |
+---------------------------------------------------------------+
| GRANT USAGE ON *.* TO `test`@`%`                              |
| GRANT SELECT, UPDATE, CREATE, DROP ON `kerry`.* TO `test`@`%` |
+---------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> revoke drop on  `kerry`.* from `test`@`%`;
Query OK, 0 rows affected (0.06 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

mysql> create role drop_tab;
Query OK, 0 rows affected (0.01 sec)
mysql> select 
    ->      table_name
    ->     ,table_type
    ->     ,concat('grant drop on ', table_schema, '.', table_name , ' to test@''%'';') as grant_cmd
    -> from information_schema.tables
    -> where table_schema='kerry';
+------------+------------+-------------------------------------+
| TABLE_NAME | TABLE_TYPE | grant_cmd                           |
+------------+------------+-------------------------------------+
| t1         | BASE TABLE | grant drop on kerry.t1 to test@'%'; |
| t2         | BASE TABLE | grant drop on kerry.t2 to test@'%'; |
+------------+------------+-------------------------------------+
2 rows in set (0.00 sec)

mysql> 

mysql> grant drop on kerry.t1 to test@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> grant drop on kerry.t2 to test@'%';
Query OK, 0 rows affected (0.00 sec)


mysql> grant drop_tab to test@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> 

此时,账号test就没有删除数据库kerry的权限了.

mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| test@%         |
+----------------+
1 row in set (0.00 sec)
mysql> drop table t1;
Query OK, 0 rows affected (0.02 sec)
mysql> drop database kerry;
ERROR 1044 (42000): Access denied for user 'test'@'%' to database 'kerry'
mysql> 

总结

关于数据库的权限,我们还是要细心与谨慎. 数据库授权,一般要秉着权限越小越好的原则,避免权限过大带来不必要的麻烦. 另外,就是MySQL这种权限设计, 其实是设计上的一大缺陷.很容易让人踩一个大坑.

扫描上面二维码关注我
如果你真心觉得文章写得不错,而且对你有所帮助,那就不妨帮忙“推荐"一下,您的“推荐”和”打赏“将是我最大的写作动力!
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.
【事件触发一致性】研究多智能体网络如何通过分布式事件驱动控制实现有限时间内的共识(Matlab代码实现)内容概要:本文围绕多智能体网络中的事件触发一致性问题,研究如何通过分布式事件驱动控制实现有限时间内的共识,并提供了相应的Matlab代码实现方案。文中探讨了事件触发机制在降低通信负担、提升系统效率方面的优势,重点分析了多智能体系统在有限时间收敛的一致性控制策略,涉及系统模型构建、触发条件设计、稳定性与收敛性分析等核心技术环节。此外,文档还展示了该技术在航空航天、电力系统、机器人协同、无人机编队等多个前沿领域的潜在应用,体现了其跨学科的研究价值和工程实用性。; 适合人群:具备一定控制理论基础和Matlab编程能力的研究生、科研人员及从事自动化、智能系统、多智能体协同控制等相关领域的工程技术人员。; 使用场景及目标:①用于理解和实现多智能体系统在有限时间内达成一致的分布式控制方法;②为事件触发控制、分布式优化、协同控制等课题提供算法设计与仿真验证的技术参考;③支撑科研项目开发、学术论文复现及工程原型系统搭建; 阅读建议:建议结合文中提供的Matlab代码进行实践操作,重点关注事件触发条件的设计逻辑与系统收敛性证明之间的关系,同时可延伸至其他应用场景进行二次开发与性能优化。
<think> 嗯,用户这次明确要求的是MySQL创建用户并赋予权限的操作指南。从用户引用[1]的内容来看,ta已经查阅过相关资料,但需要更系统化的说明。用户可能正在搭建数据库环境,或是为新项目配置权限,这类操作通常出现在运维或开发场景中。 注意到用户引用的材料里提到“省流”字样,说明ta可能偏好简洁的步骤式说明,但作为专业指导仍需保持完整性。上次提供的快速排序示例结构(分点+代码块)很清晰,这次可以延续类似风格,但需调整为重点突出SQL命令的实操性。 需要特别注意几个技术细节:一是MySQL 8.0前后版本权限命令的差异(比如CREATE USER和GRANT的分离),二是用户容易忽略的FLUSH PRIVILEGES必要性。在权限回收部分要强调REVOKE不会自动删除用户这个常见误区。 用户没有指定MySQL版本,所以准备采用兼容性较强的写法(同时标注8.0+的改动)。所有权限操作都应当包含示例代码块,这是开发者最需要的核心内容。最后补充的“注意事项”模块很有必要——特别是生产环境中%通配符的安全风险,这往往是新手容易。 相关问题设计要覆盖权限管理的延伸场景:密码策略属于安全加固,远程访问是常见需求,而权限检查能帮助调试。这些都应该在用户完成基础操作后自然延伸的知识点。 </think> 以下是 MySQL 创建用户并授予权限的完整操作指南,包含关键步骤和注意事项: ### 🔑 一、创建用户 #### 1. 基本语法 ```sql CREATE USER '用户名'@'主机' IDENTIFIED BY '密码'; ``` - `主机`:指定访问来源(`localhost`表示本地,`%`表示任意主机) - 示例:创建远程访问用户 ```sql CREATE USER 'dev_user'@'%' IDENTIFIED BY 'Str0ngP@ss!'; ``` #### 2. 验证用户创建 ```sql SELECT User, Host FROM mysql.user; -- 查看所有用户 ``` ### ⚙️ 二、授予权限 #### 1. 基础授权语法 ```sql GRANT 权限类型 ON 数据库.表 TO '用户名'@'主机'; ``` #### 2. 常用权限场景 | 权限类型 | 适用场景 | 示例 | |------------------|----------------------------|-------------------------------------------| | `ALL PRIVILEGES` | 完整数据库控制权 | `GRANT ALL ON mydb.* TO 'user'@'localhost'` | | `SELECT` | 只读访问 | `GRANT SELECT ON sales.* TO 'reporter'@'%'`| | `INSERT, UPDATE` | 数据修改权限 | `GRANT INSERT,UPDATE ON appdb.* TO 'editor'@'192.168.1.%` | | `CREATE` | 创建表/索引 | `GRANT CREATE ON testdb.* TO 'dev'@'localhost'` | #### 3. 特殊权限控制 ```sql -- 授权存储过程执行 GRANT EXECUTE ON PROCEDURE mydb.GetStats TO 'api_user'@'%'; -- 允许用户给他人授权 GRANT ALL ON mydb.* TO 'admin'@'localhost' WITH GRANT OPTION; ``` ### 🔍 三、权限管理操作 #### 1. 查看用户权限 ```sql SHOW GRANTS FOR 'dev_user'@'%'; /* 输出示例: GRANT USAGE ON *.* TO `dev_user`@`%` GRANT SELECT, INSERT ON `mydb`.* TO `dev_user`@`%` */ ``` #### 2. 回收权限 ```sql REVOKE INSERT ON mydb.* FROM 'dev_user'@'%'; -- 撤销单个权限 REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'old_user'@'%'; -- 撤销所有权限 ``` #### 3. 修改用户密码 ```sql ALTER USER 'dev_user'@'%' IDENTIFIED BY 'NewP@ss2024'; -- MySQL 5.7+ ``` #### 4. 删除用户 ```sql DROP USER 'obsolete_user'@'localhost'; ``` ### ️ 四、关键注意事项 1. **刷新权限**:执行授权或修改后必须运行 ```sql FLUSH PRIVILEGES; -- 使权限变更立即生效 ``` 2. **最小权限原则**:仅授予必要权限 3. **主机限制**:生产环境避免使用`'%'`,推荐指定IP段 4. **MySQL 8.0+变化**: ```sql CREATE USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'password'; ``` 5. **权限层级控制**: - `*.*`:全局权限 - `mydb.*`:数据库级 - `mydb.orders`:表级 ### 五、操作示例全流程 ```sql -- 创建报表用户(只读权限) CREATE USER 'report'@'192.168.1.%' IDENTIFIED BY 'R3port@2024'; GRANT SELECT ON sales.* TO 'report'@'192.168.1.%'; FLUSH PRIVILEGES; -- 验证权限 SHOW GRANTS FOR 'report'@'192.168.1.%'; ``` > 📌 **重要提示**:权限变更后务必执行`FLUSH PRIVILEGES`,否则更改将在MySQL服务重启后生效[^1]。 --- ### ❓相关问题 1. **MySQL 8.0中`caching_sha2_password`插件导致客户端连接失败如何解决?** 2. **如何批量导出MySQL所有用户的权限配置?** 3. **生产环境中如何安全配置数据库远程访问权限?** 4. **MySQL权限系统和Linux系统用户权限有何关联?** 5. **如何审计MySQL用户的权限变更历史?** [^1]: MySQL官方文档:Privilege Changes Require Flush Privileges
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值