深入浅出SQL(15)-安全性

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baby_hua/article/details/82910662

该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动!

安全性:保护你的资产

创建数据库我们已经做了很多,现在我们需要把数据库和其中的对象变得更安全,并且能做到全面控制谁对数据进行什么操作;

测试数据库依然可以使用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:让有角色的用户把同一角色授予其他人;

猜你喜欢

转载自blog.csdn.net/baby_hua/article/details/82910662