MySQL系列:12 用户管理之2 授权

开门见山

         前文讲述了MySQL用户管理之认证,当某客户端成功认证,接下来的操作就需要进行权限验证,如验证用户的select、insert、update等操作权限,shutdown、process、file等管理权限等。

MySQL授权杂货

授权层级

MySQL支持global、database、table、column等不同层级授权。同时,还可以对用户的routine(procedures & functions)等权限进行控制,具体控制项可以查看mysql.user表的列信息。如下:

管理权限

         MySQL的主要管理选项有:FILE、PROCESS:、SUPER、ALL等。

FILE:允许用户读写服务器上的文件;
PROCESS:允许用户执行show PROCESSLIST命令查看所有连接的客户端;
SUPER: 允许用户kill掉其他客户端的连接;
ALL:允许所有权限, 除了给其他用户授权;

注意:

      给其他用户授权的权限,需要在对此用户本身授权时加上WITH GRANT OPTION子句。如下,笔者用debian-sys-maint用户登录(密码在/etc/mysql/debian.cnf文件中,root用户本身没有grant权限),并创建一个super用户,赋予WITH GRANT OPTION选项。后面就可以用super给其他用户授权了。

  • root用户给test1用户授权,失败---因为root用户本身没有grant权限;

  • debian-sys-maint给super用户授权,成功;

  • 用super用户再次给test1用户授权—成功。

GRANT授权

         MySQL使用grant语句为用户授权,格式如下:

GRANT XXX1 ON database.XXX2 TO 'user'@'hostname' [ with grant option ]

其中:

  • XXX1标识具体权限,如select、insert、all privileges等,多个权限项用,分割,如下:
mysql> grant all privileges on  *.* TO 'test1'@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.16 sec)
  • with grant option表示传递grant 授权,带此子句后,被授权的user可以进一步为其他用户授权相关权限;

显示用户的grant权限

  • 显示当前用户的grant权限
mysql> show grants;
+----------------------------------------------------------------------+
| Grants for super@localhost                                           |
+----------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'super'@'localhost' WITH GRANT OPTION |
+----------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show grants for current_user();
+----------------------------------------------------------------------+
| Grants for super@localhost                                           |
+----------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'super'@'localhost' WITH GRANT OPTION |
+----------------------------------------------------------------------+
1 row in set (0.00 sec)
  • 显示指定用户权限
mysql> show grants for 'common'@'%';
+---------------------------------------------------------------+
| Grants for common@%                                           |
+---------------------------------------------------------------+
| GRANT SELECT, INSERT ON *.* TO 'common'@'%' WITH GRANT OPTION |
+---------------------------------------------------------------+
1 row in set (0.00 sec)

Grant Tables权限元数据表

MySQL使用特定的表存储权限相关的信息,即metadata。除了我们熟知的mysql.user表外,还有:db、tables_priv、columns_priv、procs_priv等;如

  • mysql.sys用户对sys数据库拥有权限;

       

  • tables_priv表记录用户对表的权限;

FLUSH PRIVILEGES语句

         我们在MySQL系列:9 存储引擎中已经知道,表是存储在表空间(文件)中的。mysqld在启动时将权限相关表读入到内存中,以免频繁磁盘访问开销。当我们使用类似update、insert直接修改表时,其内存副本并不生效。因而需要FLUSH PRIVILEGES语句指示mysqld重新加载权限表。

  • 关于skip-grant-tables选项的详细解释:

上篇博文中提到,若忘记mysql登录密码,可以使用skip-grant-tables选项重启服务进程,然后免密登录修改指定用户密码。但是修改之前需要先FLUSH PRIVILEGES重新加载权限表。原因就是因为skip-grant-tables选项启动mysqld进程时,内存中根本没有选项表的数据,所以无法更改。

  • 权限表内存副本自动刷新条件

使用create user、grant、revoke等子句修改相关用户权限时,MySQL自动刷新内存副本(具体不同MySQL版本略有不同),因为当使用alter命令修改权限时,需要flush才能生效。

回收账户权限

         可使用revoke XXX from命令回收账户权限,如下:

mysql> show grants for 'common'@'%' ;
+---------------------------------------------------------------+
| Grants for common@%                                           |
+---------------------------------------------------------------+
| GRANT SELECT, INSERT ON *.* TO 'common'@'%' WITH GRANT OPTION |
+---------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> revoke INSERT ON *.* from 'common'@'%';
Query OK, 0 rows affected (0.03 sec)

mysql> show grants for 'common'@'%' ;
+-------------------------------------------------------+
| Grants for common@%                                   |
+-------------------------------------------------------+
| GRANT SELECT ON *.* TO 'common'@'%' WITH GRANT OPTION |
+-------------------------------------------------------+
1 row in set (0.00 sec)

SHOW PROCESSLIST

         此命令显示所有已连接的客户线程ID(并不是整个mysqld守护进程的所有线程)和正在执行的命令,mysql对每个连接创建一个线程(thread_handling选项,one-thread-per-connection)。如下:

mysql> SHOW PROCESSLIST;
+----+-------+-----------+------+---------+------+----------+------------------+
| Id | User  | Host      | db   | Command | Time | State    | Info             |
+----+-------+-----------+------+---------+------+----------+------------------+
| 11 | super | localhost | NULL | Query   |    0 | starting | SHOW PROCESSLIST |
| 12 | root  | localhost | NULL | Sleep   |    6 |          | NULL             |
+----+-------+-----------+------+---------+------+----------+------------------+
2 rows in set (0.00 sec)

设置账户资源限制

         mysql.user表的最后记录是关于资源限制的信息,如可以设置同一用户的同时连接数。如下:

说明:

  1. 首先用alter user 'common'@'%' with MAX_USER_CONNECTIONS 1;设置最大用户连接数为1;
  2. 同时开两个窗口进行链接,第二次链接会报连接超限。第一次链接已成功(show processlist)。

总结

         如上两篇博文详细的介绍了MySQL的认证/授权机制,针对不同的MySQL版本,其控制细节略有差异。读者在实际应用中,应根据具体场景、具体版本合理的设置应用用户的权限,以实现MySQL数据库安全稳定的运行。

猜你喜欢

转载自blog.csdn.net/zhaogang1993/article/details/100052052