ITPub博客

首页 > 数据库 > MySQL > 涂抹MySQL--第5章 MySQL数据库中的权限体系 - 5.2权限授予与回收(3)

涂抹MySQL--第5章 MySQL数据库中的权限体系 - 5.2权限授予与回收(3)

原创 MySQL 作者:junsansi 时间:2014-06-30 10:07:42 0 删除 编辑

5.2.3 查看和收回用户权限

不管是授予还是想收回用户的权限,通常我们首先需要知道用户当前都拥有什么权限。查询用户权限可以使用SHOW GRANTS语句,SHOW GRANTS的语法比较简单,就一行:

SHOW GRANTS [FOR user]

其中FOR user还是个可选项,用于指定要查询的目标用户,如果不指定的话,则默认显示当前用户拥有的权限,效果等同于SHOW GRANTS FOR CURRENT_USER()

如果之前从未用过,那么SHOW GRANTS语句显示的结果可能会出乎意料,它返回的结果并不是某个权限类型的关键字,而是授权语句。

例如,查看用户jss_grant@192.168.30.203都拥有哪些权限,执行语句如下:

(system@localhost) [(none)]> show grants for jss_grant@192.168.30.203;

+-----------------------------------------------------------------------------------------------------------------------+

| Grants for jss_grant@192.168.30.203                                                                                   |

+-----------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'jss_grant'@'192.168.30.203' IDENTIFIED BY PASSWORD '*284578888014774CC4EF4C5C292F694CEDBB5457' |

| GRANT SELECT ON `jssdb`.* TO 'jss_grant'@'192.168.30.203'                                                             |

| GRANT SELECT ON `mysql`.`user` TO 'jss_grant'@'192.168.30.203'                                                        |

+-----------------------------------------------------------------------------------------------------------------------+

3 rows in set (0.00 sec)

从上述返回的结果可以看到,用户jss_grant@192.168.30.203拥有三项个权限:查询mysql.user表的查询,查询jssdb数据库下所有对象的权限,以及登录MySQL数据库的权限。要我说,MySQL数据库SHOW GRANTS语法最喜人之处在于,创建用户和授权语法都列出来了。

尽管前面我已经无数次提到过,直接查询mysql库中的数据字典表,来修改或查看用户的权限信息,但我觉着如果是要查看某个用户的权限,那么使用SHOW GRANTS语句才是最好的方式,功能超强而且易用。

 

要收回用户权限,与之对应的命令是REVOKE,它的语法从定义上分为两种:

l REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ...

    ON [object_type] priv_level FROM user [, user] ...

 

l REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...

前者用来处理指定的权限,有很多选项,这些选项的定义与GRANT中同名选项定义一模一样,这里不再复述。后者功能较为独立,可以理解成专用于清除用户权限。

我们先来尝试收回jss_grant@'192.168.30.203'用户,拥有的mysql.user表对象的select权限,执行revoke命令如下:

(system@localhost) [(none)]> revoke select on mysql.user from jss_grant@192.168.30.203;

Query OK, 0 rows affected (0.00 sec)

 

(system@localhost) [(none)]> show grants for jss_grant@192.168.30.203;

+-----------------------------------------------------------------------------------------------------------------------+

| Grants for jss_grant@192.168.30.203                                                                                   |

+-----------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'jss_grant'@'192.168.30.203' IDENTIFIED BY PASSWORD '*284578888014774CC4EF4C5C292F694CEDBB5457' |

| GRANT SELECT ON `jssdb`.* TO 'jss_grant'@'192.168.30.203'                                                             |

+-----------------------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

收回某个普通的指定权限立竿见影。注意,我说的是普通权限。有哪些权限不普通呢,如果此刻你的内心浮现出这个问题,说明看书不认真啊小盆友,在前面介绍GRANT语句时就曾提到过的,比如说USAGE权限,这个权限用户一经创建就会拥有,并且无法通过REVOKE 语句收回。你要不相信哪,咱们来看一看:

(system@localhost) [(none)]> revoke usage on *.* from 'jss_grant'@'192.168.30.203';

Query OK, 0 rows affected (0.00 sec)

操作提示成功,但是这是个假象,可以通过查看jss_grant用户拥有的权限来验证:

(system@localhost) [(none)]> show grants for jss_grant@192.168.30.203;

+-----------------------------------------------------------------------------------------------------------------------+

| Grants for jss_grant@192.168.30.203                                                                                   |

+-----------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'jss_grant'@'192.168.30.203' IDENTIFIED BY PASSWORD '*284578888014774CC4EF4C5C292F694CEDBB5457' |

| GRANT SELECT ON `jssdb`.* TO 'jss_grant'@'192.168.30.203'                                                             |

+-----------------------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

毫无变化。前面revoke之所以没有报错,也跟MySQL在语句执行上的设定有关系,比方说,您可以尝试revoke任意权限 from user,它都不会报错的,我们之前提到过,MySQL的返回就是这个德性:Query OK, 0 rows affected。

此外前面三思还提到过特殊的ALL PRIVILEGES,这个权限也不像字面意义那么简单,所谓“所有权限”指的不是所有哟。你要不相信呀,咱们再来看一看,对jss_grant@'192.168.30.203'用户执行revoke ALL PRIVILEGES

(system@localhost) [(none)]> revoke all privileges on *.* from jss_grant@'192.168.30.203';

Query OK, 0 rows affected (0.00 sec)

提示信息总是这样,我们能猜的到开头,不过能猜的对结局不,还是实际验证一下吧:

(system@localhost) [(none)]> show grants for jss_grant@192.168.30.203;

+-----------------------------------------------------------------------------------------------------------------------+

| Grants for jss_grant@192.168.30.203                                                                                   |

+-----------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'jss_grant'@'192.168.10.203' IDENTIFIED BY PASSWORD '*284578888014774CC4EF4C5C292F694CEDBB5457' |

| GRANT SELECT ON `jssdb`.* TO 'jss_grant'@'192.168.30.203'                                                             |

+-----------------------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

又是毫无作用。那个特殊的USAGE权限就不说了,可是ALL PRIVILEGES居然连小小的普通的SELECT权限都没能收回,这还称得上ALL吗?呃,这个,称得上,它只是功能的设计并不像我们想像的那样而已。这几个知识点是MySQL数据库的权限体系设计上的细节,如不注意就有可能错误理解这些设计。

前后两个操作尽管看起来结果相同,但结论是完全不同的,前者是由于USAGEMySQL权限体系中,对于用户的特殊意义,后者是由于系统设计层的因素。MySQL数据库中的权限,操作时授予和收回的权限级别(priv_level)必须对应,否则无法成功回收。

就上面这个例子中,授予jss_grant@'192.168.30.203'用户SELECT权限时,是基于jssdb这样一个库级授予的,那么回收时,也必须明确指定是基于库级回收,如果指定all on *.*,则无法收回jssdb.*的权限,这也正是MySQL数据库权限粒度分级的特点。

因此,如果要让REVOKE ALL PRIVILEGES语句正确有效执行,就应该明确指定on jssdb.*,例如:

(system@localhost) [(none)]> revoke all privileges on jssdb.* from jss_grant@'192.168.30.203';

Query OK, 0 rows affected (0.00 sec)

 

(system@localhost) [(none)]> show grants for jss_grant@192.168.30.203;

+-----------------------------------------------------------------------------------------------------------------------+

| Grants for jss_grant@192.168.30.203                                                                                   |

+-----------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'jss_grant'@'192.168.30.203' IDENTIFIED BY PASSWORD '*284578888014774CC4EF4C5C292F694CEDBB5457' |

+-----------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

这下终于成功将权限收回了。

 

三思有过多年的ORACLE数据库使用经验,在尝试使用和学习MySQL数据库期间感触很深,MySQL数据库设计的确实很有特点,我想对于初学者,只要小脑袋瓜没有停止思考,一定会持续不断冒出各种各样的问题。对于用户的权限回收,经过前面一些演示,想必朋友会又会有新的疑问:若用户拥有各种不同级别不同粒度不同的权限,回收时难道也必须一一指定回收吗,这岂不太过繁琐了。关于这点,我可以负责任的说,把心踏踏实实搁肚子里头吧,MySQL数据库就跟繁琐俩字不沾边,做为一款开源的轻量级数据库,MySQL就没有什么复杂的特性,自然也不会有繁琐的操作。

对于前面这个疑问,如果确定要干净利索的清除某个用户的所有权限,并且还要保留这个用户(这是什么变态需求),那么,REVOKE语句的第二种语法派上用场了:REVOKE ALL PRIVILEGES, GRANT OPTION FROM user。

这是个固定语法,功能正是用于收回用户的所有权限,不管授予用户的是什么权限级别什么对象的什么权限,一条语句执行下去,直接将用户恢复至裸身(USAGE)状态。

当前,jss_grant@'192.168.30.203'用户有各类权限如下:

(system@localhost) [(none)]> show grants for jss_grant@'192.168.30.203';                                          

+-------------------------------------------------------------------------------------------------------------------+

| Grants for jss_grant@192.168.30.203                                                                                   |

+-------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'jss_grant'@'192.168.30.203' IDENTIFIED BY PASSWORD '*284578888014774CC4EF4C5C292F694CEDBB5457' |

| GRANT UPDATE, DELETE ON `jssdb`.* TO 'jss_grant'@'192.168.30.203'                                                     |

| GRANT ALTER ON `jssdb_mc`.* TO 'jss_grant'@'192.168.30.203'                                                           |

| GRANT SELECT ON `mysql`.`user` TO 'jss_grant'@'192.168.30.203'                                                        |

+-------------------------------------------------------------------------------------------------------------------+

4 rows in set (0.00 sec)

怎么一次性收回所有权限呢,执行REVOKE语句如下:

(system@localhost) [(none)]> revoke all,grant option from jss_grant@'192.168.30.203';

Query OK, 0 rows affected (0.00 sec)

 

(system@localhost) [(none)]> show grants for jss_grant@192.168.30.203;

+-----------------------------------------------------------------------------------------------------------------------+

| Grants for jss_grant@192.168.30.203                                                                                   |

+-----------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'jss_grant'@'192.168.30.203' IDENTIFIED BY PASSWORD '*284578888014774CC4EF4C5C292F694CEDBB5457' |

+-----------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

你看,你看,用户的权限悄悄地在改变。

5.2.4 删除用户

我想不出一个仅拥有"USAGE"权限的用户存在的意义,干脆,删了它吧。怎么,您担心会丢失数据,影响系统稳定,放心吧,一个失势的人对组织是没什么危险的,甭管它是谁,甭管它之前多红歌声多么嘹亮,也甭管它之前手握多少资源,只要权利被收回,它就立刻什么都不是,这是由当前的制度所决定的。

很多人之所以担心删用户会丢数据,主要是受其它数据库产品的影响,比如说ORACLE中删除用户(或其它对象比如表空间),如果该用户下有很多的对象,那么删除用户的同时也会把这些对象及关联的数据统统删除,尽管ORACLE会人性化地提醒你删除的用户下仍然存在数据,但如果强制级联删除(附加CASCADE选项),那么该删就还是删了。

MySQL的删除用户语法中就不存在CASCADE的选项,为什么不存在呢,并不是MySQL对数据的保护不如ORACLE那么上心,而是由于最重要的一条与ORACLE不同的机制决定,MySQL数据库中的对象保存并不是依赖于用户,而是依赖于库(database),用户被删除没有任何关系,对象仍在,好好的保存在存储它的数据库中。

因此,MySQL数据库中的用户删了就删了,如果外部应用不使用该用户的话,那么我们可以认为该用户被删除无影响。即使发现真的删错了,该用户其实早就立志将一生奉献给镰刀斧头帮,并且作风过硬,对party和国家无限忠诚,party让咬谁就咬谁。想给它恢复身份的话也很简单,这不就是组织上一句话的事儿嘛,只要重新向mysql.user表重新插入记录(注册建档),并授予所需权限即可(授予官阶),至于底层数据的意见那是完全可以忽视的。

看我说的这么笃定,下面就实际册个试试吧。MySQL删除用户的语法非常简单:

DROP USER user [, user] ...

从语法上大家想必也都看出来了,也可以一次性删除多个用户,这里三思就准备一步删除之前创建的jss_grantjss_insertjss_ip几个用户,执行drop user命令如下:

(system@localhost) [(none)]> drop user jss_grant@192.168.30.203, jss_insert@192.168.30.203, jss_ip@192.168.30.203;

Query OK, 0 rows affected (0.00 sec)

需要说明的一点是,DROP USER不会自动中止已连接的用户会话,也就是说被删的用户如果在删前已经连接上了服务器,并且连接尚未中断,那它此时还能继续执行一定的操作,只是,它的身份已经变成了黑户。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7607759/viewspace-1199560/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-21

  • 博文量
    640
  • 访问量
    4108852