该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动!
安全性:保护你的资产
创建数据库我们已经做了很多,现在我们需要把数据库和其中的对象变得更安全,并且能做到全面控制谁对数据进行什么操作;
测试数据库依然可以使用mark_list;
随着业务量的增长,Mark雇佣了更多的人:
现在能操作数据库的人越来越多,我们必须避免错误的人做错误的事;
比如,新进员工只能SELECT数据,但是不可以INSERT或是UPDATE;
再如,只能访问特定的表,而不会不小心就能执行DROP TABLE;
统计下可能出现的行为:
SELECT操作、INSERT操作、UPDATE操作、DELETE操作;
ALTER操作、DROP TABLE操作等;
用户账户:
SQL允许我们控制对数据库能做和不能做的事情,前提是需要为每个数据库用户新建一个用户账户(user account);
保护用户账户:root
默认,第一位用户——根用户(root)具有所有数据库操控能力;
根用户需要为其他用户创建账号;
根用户也是有密码的:在安装MySQL时我们已经设置了密码;
也可以使用SQL语句设置根用户密码;
MySQL设定根用户密码:
localhost是安装RDBMS的计算机地址,是默认参数值,可选;
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('Hua13342278947');
这条SQL会报错,我们使用help查看password:
原来这个功能已经被移除了;
mysql> help password;
This function was removed in MySQL 8.0.11.
值得注意的是,如何设定密码并非重点,重点在于一定要设置密码;
SQL存储用户信息:
用户信息是存储在表中的,SQL以数据库存储他本身的数据;
这包括用户信息以及对特定数据库的操作权限等;
在数据库系统中有一个mysql数据库,其中的user表如下(部分):
这个表有很多列,前边的列表示的就是相关用户的权限;
我们看到root根用户的权限最大;
添加新用户:
mysql> CREATE USER hua1
-> IDENTIFIED BY 'hua123’;
我们看到,hua1的几乎没有权限,因为权限需要root去分配;(这个查询出来的权限并不能代表hua1对某个表的权限)
查询该表中hua1相关更方便的SQL:
mysql> SELECT * FROM mysql.User WHERE User = 'hua1' \G;
*************************** 1. row ***************************
Host: %
User: hua1
Select_priv: N
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Reload_priv: N
Shutdown_priv: N
Process_priv: N
File_priv: N
其实在新建用户时就可以分配权限,我们后面在来看如何将创建用户和分配权限结合,先来看看如何单独分配权限;
测试数据库mark_list中表:
+---------------------+
| Tables_in_mark_list |
+---------------------+
| contact_interest |
| interests |
| job_current |
| job_desired |
| job_list |
| my_contacts |
| profession |
| v_contacts |
| v_engineers |
| zip_code |
+---------------------+
GRANT:授予
新用户hua1不能对数据库中的任何对象执行任何SQL命令,因为他没有任何权限;
GRANT语句可以为用户授予操作数据库的特权;
GRANT的作用:
1)仅允许部分用户修改特定表;
2)特定表的数据仅允许部分用户访问;
3)就算在表中,也可能需要权限:部分用户可看到特定列,但其他人不行;
使用GRANT语句可以控制用户对表和列可执行的操作;
简单的GRANT语句:
利用GRANT语句把my_contacts表的SELECT操作权限授予hua1;
有GRANT TO语句完成;
mysql> GRANT SELECT
-> ON my_contacts
-> TO hua1;
Query OK, 0 rows affected (0.04 sec)
这是一个很简单的SQL,但却能说明GRANT的使用;
查看GRANT的权限:
我们可以使用如下SQL查看已经赋予给hua1的权限;
不使用FOR表示查看当前用户权限;
mysql> SHOW GRANTS FOR hua1;
+---------------------------------------------------------+
| Grants for hua1@% |
+---------------------------------------------------------+
| GRANT USAGE ON *.* TO `hua1`@`%` |
| GRANT SELECT ON `mark_list`.`my_contacts` TO `hua1`@`%` |
+---------------------------------------------------------+
类似的,我们也查看了部分给root的权限:
mysql> SHOW GRANTS FOR root@localhost;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE,………, CREATE ROLE, DROP ROLE ON *.* TO `root`@`localhost` WITH GRANT OPTION
为了能让hua1使用联接和子查询,还需要授予他数据库中其他表的权限:
每次授予表的权限都需要另写一段GRANT语句;
示例GRANT语句:
1)插入权限:
GRANT INSERT ON my_contacts TO hua1;
2)删除权限:
GRANT DELETE ON my_contacts TO hua1;
3)授予删除权限且hua1可以把这个权限授予其他人:
GRANT DELETE ON my_contacts TO hua1 WITH GRANT OPTION;
4)只能从表中选择指定列的权限:
GRANT SELECT(last_name,first_name) ON my_contacts TO hua1;
5)一次性授予多个权限:
GRANT SELECT, INSERT ON my_contacts TO hua1;
6)ALL指代 选择SELECT 更新UPDATE 插入INSERT 删除DELETE 表的权限:
GRANT ALL ON my_contacts TO hua1;
7)将权限授予多个人:
GRANT ALL ON my_contacts TO hua1, hua2;
8)将选择权限授予mark_list数据库的所有表:
GRANT SELECT ON mark_list.* TO hua1;
GRANT的各种变化:
前面的实例只是一部分,接下来让我们看看GRANT的主要的几种变化形式;
整理如下;
1)可用同一个GRANT语句为多个用户设定权限;
2)WITH GRANT OPTION 让用户能把刚刚获得的权限授予其他用户;
3)指定用户可于某张表中使用的列,而不是允许用户操作整张表;
SELECT权限也仅限于指定列,用户看到的输出将出自指定的列;
4)一段语句可对表指定超过一种权限;
列出所有要授予用户的表操作权限,并以逗号分隔每种权限;
5)GRANT ALL把SELECT UPDATE INSERT DELETE指定表内容的权限都授予用户了,是一种缩写;
6)使用database_name.* 可把权限范围运用到数据库中的每张表上;
与SELECT语句的通配符*相似,代表数据库中的所有表;
撤销权限:REVOKE
与GRANT类似,只需要吧GRANT换成REVOKE,把TO换成FROM;
mysql> REVOKE SELECT
-> ON my_contacts
-> FROM hua1;
Query OK, 0 rows affected (0.10 sec)
mysql> SHOW GRANTS FOR hua1;
+----------------------------------+
| Grants for hua1@% |
+----------------------------------+
| GRANT USAGE ON *.* TO `hua1`@`%` |
+----------------------------------+
1 row in set (0.00 sec)
添加授予权限:
mysql> GRANT SELECT
-> ON my_contacts
-> TO hua1
-> WITH GRANT OPTION;
撤销授予权限:
会撤销所有权限的授予权限;
mysql> REVOKE GRANT OPTION
-> ON my_contacts
-> FROM hua1;
只撤销WITH GRANT OPTION,但不触及权限;
仍然可以SELECT,但不能把SELECT权限授予其他人;
了解到的SQL有两种,但并不好用,我们重新授权,来尝试下;?(如果有人知道的麻烦留言指导下,多谢!)
mysql> REVOKE GRANT OPTION
-> ON SELECT
-> ON my_contacts
-> FROM hua1;
mysql> REVOKE GRANT OPTION
-> FOR SELECT
-> ON my_contacts
-> FROM hua1;
显然这两条都没成功:
mysql> SHOW GRANTS FOR hua1;
+---------------------------------------------------------------------------+
| Grants for hua1@% |
+---------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `hua1`@`%` |
| GRANT SELECT ON `mark_list`.`my_contacts` TO `hua1`@`%` WITH GRANT OPTION |
+---------------------------------------------------------------------------+
撤销授予许可的特殊场景:
撤销GRANT OPTION时,如果root授予了hua1 select权限,hua1又授予hua2;
在root撤销hua1的GRANT OPTION时,有hua1授予hua2的GRANT OPTION也会被撤销掉;
有两个关键字可以控制撤销的范围;
RESTRICT和CASCADE:
具备精确度的撤销操作;
CASCADE:
使用CASCADE移除目标用户的权限后,如果目标用户已将该权限授予他人,则连同被授予者的权限一起移除;
如果目标用户已将该权限授予他人,使用RESTRICT则会受到错误,因为有人会收到REVOKE的影响,而RESTRICT不允许这样做;
但悲剧的是这两个关键字并不好用:?(如果有人知道的麻烦留言指导下,多谢!)
mysql> REVOKE INSERT
-> ON my_contacts
-> FROM hua1 CASCADE;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASCADE' at line 3
mysql> REVOKE INSERT
-> ON my_contacts
-> FROM hua1 RESTRICT;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RESTRICT' at line 3
对于列权限的REVOKE:
mysql> GRANT SELECT(last_name,first_name) ON my_contacts TO hua1;
mysql> REVOKE SELECT(last_name,first_name) ON my_contacts FROM hua1;
几乎所有针对列的权限都没有用;
MySQL授予全局权限:
GRANT SELECT ON *.* TO hua1;指对所有的数据库,所有的表;
共享账号的问题:
虽然有些公司的确只在一个数据库账号下运作,但是这并不安全;
所以,我们需要授予一群人所需权限,同时又让他们每个人都有自己的账户的方式——这种方式就是角色;
角色:
角色是把特定权限汇集的组,再把组权限授予一群人的方式;
角色成为一个数据库对象;
创建角色:
mysql> CREATE ROLE hua;
mysql> CREATE ROLE hua;
给角色授权:
为角色授予权限时,直接把角色当成用户就好了;
mysql> GRANT SELECT
-> ON my_contacts
-> TO hua;
mysql> SHOW GRANTS FOR hua;
+--------------------------------------------------------+
| Grants for hua@% |
+--------------------------------------------------------+
| GRANT USAGE ON *.* TO `hua`@`%` |
| GRANT SELECT ON `mark_list`.`my_contacts` TO `hua`@`%` |
+--------------------------------------------------------+
使用角色:
把角色’授予’给用户;
mysql> GRANT hua
-> TO hua1;
Query OK, 0 rows affected (0.10 sec)
mysql> SHOW GRANTS FOR hua1;
+----------------------------------+
| Grants for hua1@% |
+----------------------------------+
| GRANT USAGE ON *.* TO `hua1`@`%` |
| GRANT `hua`@`%` TO `hua1`@`%` |
+----------------------------------+
卸除角色:
不再需要的时候,卸除即可;
mysql> DROP ROLE hua;
Query OK, 0 rows affected (0.01 sec)
mysql> SHOW GRANTS FOR hua;
ERROR 1141 (42000): There is no such grant defined for user 'hua' on host '%'
mysql> SHOW GRANTS FOR hua1;
+----------------------------------+
| Grants for hua1@% |
+----------------------------------+
| GRANT USAGE ON *.* TO `hua1`@`%` |
+----------------------------------+
可以看到:
使用中的角色也可以被卸除,但一定要注意用户是否会因此失去必要权限;
影响的范围也是指定角色下的用户;
用户可以身兼多个角色,但需要确认不同角色之间的权限不冲突;
否定性的权限优于授予性的权限;
撤销角色:
和撤销权限类似;
mysql> GRANT SELECT
-> ON my_contacts
-> TO hua;
Query OK, 0 rows affected (0.05 sec)
mysql> GRANT hua
-> TO hua1;
Query OK, 0 rows affected (0.09 sec)
mysql> REVOKE hua
-> FROM hua1;
Query OK, 0 rows affected (0.01 sec)
加上WITH ADMIN OPTION的角色:
GRANT有WITH GRANT OPTION类似,角色有WITH ADMIN OPTION;
这个功能让具有该角色的每名用户都能把角色授予他人;
mysql> GRANT hua
-> TO hua1
-> WITH ADMIN OPTION;
Query OK, 0 rows affected (0.01 sec)
mysql> SHOW GRANTS FOR hua1;
+-------------------------------------------------+
| Grants for hua1@% |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO `hua1`@`%` |
| GRANT `hua`@`%` TO `hua1`@`%` WITH ADMIN OPTION |
+-------------------------------------------------+
现在,hua1已经具有了管理员admin权限;他可以把角色授予其他人;
撤销角色一样可以使用关键字CASCADE和RESTRICT来控制REVOKE范围,前提是两者可用;
结合CREATE USER与GRANT:
使用用户名的时候,RDBMS会先检查存在性,不存在则会自动创建;
很遗憾这种方式也不再可用;?(如果有人知道的麻烦留言指导下,多谢!)
mysql> GRANT SELECT
-> ON my_contacts
-> TO hua2
-> IDENTIFIED BY 'hua123';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY 'hua123'' at line 4
总结:
有些关键字和功能没能实现,待明白个中原委,另行补充;
1.CREATE USER:创建用户并设置密码;
2.GRANT:授予用户权限,控制用户对数据库的操作范围;
3.WITH GRANT OPTION:让用户把自己获得授权在授予其他人;
4.REVOKE:撤销权限;
5.ROLE:角色是指一组权限,他能把一组特定权限一次授予多名用户;
6.WITH ADMIN OPTION:让有角色的用户把同一角色授予其他人;