文本使用翻译工具协助翻译,存在明显机翻味,同时加入了个人一些实际操做看法。html
翻译这篇文章,源于我在最新(8.0.16)版本的MySQL使用root用户建立用户并授予全部(all)权限后,出现没法经过revoke all
撤销新建用户的全部权限,后在官网得知这是8.0.16新出的一个权限,又因为本人捉急的英语水平和直接用翻译页面的错误翻译,因而尝试手动调整翻译内容,便于理解,便有了本文,欢迎大佬指出、完善翻译。mysql
本系列共三部分:sql
若要修改用户,必须在MySQL架构上具备CREATE USER权限或UPDATE权限。在MySQL 8.0.16中咱们添加了SYSTEM_USER动态权限,以保护用户不受第一种状况的影响:其余拥有CREATE USER权限的用户进行修改。具备SYSTEM_USER权限的账户不能被没有SYSTEM_USER的账户修改,即便该账户具备CREATE USER权限数据库
在本文中,咱们将讨论第一个用例。下一篇博客文章(原文)将介绍如何防止用户被MySQL模式上具备UPDATE权限的账户所修改服务器
SYSTEM_USER权限强制执行这样的约定:若是要修改授予SYSTEM_USER权限的用户,那么除了修改用户所需的权限外,还须要具备SYSTEM_USER权限。换句话说,拥有SYSTEM_USER和CREATE权限的用户能够修改拥有SYSTEM_USER权限的用户架构
下面咱们经过例子更好的理解:运维
在实际操做中,在不改动配置下,不能建立空密码的用户:
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
,但这并不影响教程所要表达的意思ide
mysql> CREATE USER admin_user, elite_user; #建立admin_user用户和elite_user用户
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT CREATE USER ON *.* TO admin_user; #赋予admin_user用户CREATE USER权限
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT SYSTEM_USER ON *.* TO elite_user; #赋予elite_user用户SYSTEM_USER权限
Query OK, 0 rows affected (0.00 sec)
复制代码
尝试在admin_user用户会话下更改elite_user用户的密码函数
mysql> SELECT USER();
+----------------------+
| USER() |
+----------------------+
| admin_user@localhost |
+----------------------+
1 row in set (0.00 sec)
mysql> ALTER USER elite_user IDENTIFIED BY 'blahblah';
ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation
复制代码
显然是不能够的工具
返回到root用户会话下,并建立另外一个具备这两种权限的用户
mysql> CREATE USER power_user; #建立power_user用户
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT CREATE USER, SYSTEM_USER ON *.* TO power_user; #赋予power_user用户CREATE USER和SYSTEM_USER权限
Query OK, 0 rows affected (0.01 sec)
复制代码
尝试经过新建立的用户修改power_user密码
mysql> SELECT USER();
+------------------------+
| USER() |
+------------------------+
| power_user@localhost |
+------------------------+
1 row in set (0.00 sec)
mysql> ALTER USER power_user IDENTIFIED BY 'blahblah';
Query OK, 0 rows affected (0.01 sec)
复制代码
是能够成功修个power_user的密码的
若是将角色授予用户,则用户只有在激活该角色以后才能在给定会话中得到该角色的功能。若是用户没有被直接授予SYSTEM_USER,但只能经过一个或多个角色授予,则除非激活了具备SYSTEM_USER的角色,不然用户的会话不具备SYSTEM_USER。一旦激活了这样的角色,用户就可以修改具备SYSTEM_USER特权的其余用户。
咱们经过例子来理解
建立具备SYSTEM_USER权限的角色,将该角色授予咱们在前面的示例中建立的admin_user
mysql> CREATE ROLE elite_role; #建立elite_role角色
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT SYSTEM_USER ON *.* TO elite_role; #赋予elite_role角色SYSTEM_USER权限
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT elite_role to admin_user; #赋予admin_user用户elite_role角色
Query OK, 0 rows affected (0.01 sec)
复制代码
【MySQL8.0-新特性-role】role能够看作一个权限的集合,这个集合有一个统一的名字role名。能够给多个帐户统一的某个role的权限权限的修改直接经过修改role来实现,不须要每一个帐户一个一个的grant权限,方便运维和管理。role能够建立、删除、修改并做用到他管理的帐户上。
即便经过将角色授予的admin_user,该用户也只能在激活该角色以后才能修改elite_user
mysql> SHOW GRANTS;
+----------------------------------------------+
| Grants for admin_user@% |
+----------------------------------------------+
| GRANT CREATE USER ON *.* TO `admin_user`@`%` |
| GRANT `elite_role`@`%` TO `admin_user`@`%` |
+----------------------------------------------+
2 rows in set (0.00 sec)
mysql> ALTER USER elite_user IDENTIFIED BY 'blahblah'; #更改elite_user用户的密码
ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation #更改失败
mysql> SET ROLE elite_role; #激活elite_role角色
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW GRANTS;
+----------------------------------------------+
| Grants for admin_user@% |
+----------------------------------------------+
| GRANT CREATE USER ON *.* TO `admin_user`@`%` |
| GRANT SYSTEM_USER ON *.* TO `admin_user`@`%` |
| GRANT `elite_role`@`%` TO `admin_user`@`%` |
+----------------------------------------------+
3 rows in set (0.00 sec)
mysql> ALTER USER elite_user IDENTIFIED BY 'blahblah'; #更改elite_user用户的密码
Query OK, 0 rows affected (0.01 sec) #更改为功
复制代码
只有在具备授予GRANT选项的SYSTEM_USER权限的状况下。正如咱们所看到的,即便用户拥有SUPER权限与GRANT OPTION,它也不能从其余用户中撤销SYSTEM_USER
mysql> SHOW GRANTS;
+-----------------------------------------------------------------------+
| Grants for admin_user@% |
+-----------------------------------------------------------------------+
| GRANT SUPER, CREATE USER ON *.* TO `admin_user`@`%` WITH GRANT OPTION |
+-----------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> REVOKE SYSTEM_USER ON *.* FROM elite_user;
ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation
复制代码
若是用户拥有SYSTEM_USER权限,则能够撤消其余用户的SYSTEM_USER权限
mysql> SHOW GRANTS;
+-----------------------------------------------------------------------+
| Grants for admin_user@% |
+-----------------------------------------------------------------------+
| GRANT SUPER, CREATE USER ON *.* TO `admin_user`@`%` WITH GRANT OPTION |
| GRANT SYSTEM_USER ON *.* TO `admin_user`@`%` WITH GRANT OPTION |
+-----------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> REVOKE SYSTEM_USER ON *.* FROM power_user;
Query OK, 0 rows affected (0.01 sec)
复制代码
若是你拥有SET_USER_ID权限,那你能够建立一个带有DEFINER属性的存储过程,并将DEFINER属性设置为任何用户
也能够经过在DEFINER属性中具备SYSTEM_USER、clever、no权限的用户来授予本身SYSTEM_USER权限
嗯,不太好。若要将DEFINER属性设置为具备SYSTEM_USER权限的用户,还必须在SET_USER_ID权限以外拥有SYSTEM_USER权限。
经过例子了解:
mysql> SHOW GRANTS FOR admin_user; #显示授予admin_user的权限
+----------------------------------------------------------------+
| Grants for admin_user@% |
+----------------------------------------------------------------+
| GRANT CREATE USER ON *.* TO `admin_user`@`%` WITH GRANT OPTION |
| GRANT SET_USER_ID ON *.* TO `admin_user`@`%` |
| GRANT ALL PRIVILEGES ON `test`.* TO `admin_user`@`%` |
+----------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> SHOW GRANTS FOR elite_user; #显示授予elite_user的权限
+----------------------------------------------------------------+
| Grants for power_user@% |
+----------------------------------------------------------------+
| GRANT EXECUTE ON *.* TO `elite_user`@`%` WITH GRANT OPTION |
| GRANT SYSTEM_USER ON *.* TO `elite_user`@`%` WITH GRANT OPTION |
+----------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> SHOW GRANTS FOR regular_user; #显示授予regular_user的权限
+--------------------------------------------+
| Grants for regular_user@% |
+--------------------------------------------+
| GRANT EXECUTE ON *.* TO `regular_user`@`%` |
+--------------------------------------------+
1 row in set (0.00 sec)
复制代码
admin_user尝试使用具备SYSTEM_USER权限的DEFINER建立一个存储过程,可是它会获得一个错误。
mysql> CREATE DEFINER= elite_user PROCEDURE test.gp() GRANT SYSTEM_USER ON *.* TO CURRENT_USER();
ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation
复制代码
试图在存储过程当中授予SYSTEM_USER权限的尝试也被阻止
mysql> CREATE DEFINER= regular_user PROCEDURE test.gp() GRANT SYSTEM_USER ON *.* TO CURRENT_USER();
Query OK, 0 rows affected (0.01 sec)
mysql> call test.gp();
ERROR 1227 (42000): Access denied; you need (at least one of) the GRANT OPTION privilege(s) for this operation
复制代码
接受DEFINER属性的其余数据库对象的行为与上面演示的相似。这些对象是:函数、视图、触发器、事件。
在角色的状况下,将会有一些有趣的场景。我不该该一我的玩,因此我把这些场景留给你去尝试
做为起点,必须至少有一个具备SYSTEM_USER权限的用户。在升级服务器时,具备SET_USER_ID权限的用户将被授予SYSTEM_USER权限。若是没有用户拥有SET_USER_ID权限,那么拥有SUPER权限的用户将被授予SYSTEM_USER权限。咱们选择SET_USER_ID来做出这个决定,由于它是管理权限之一。它使用户可以在视图或存储过程的DEFINER属性中指定任何账户,这是SYSTEM_USER应用到的操做。
函数返回链接到服务器的当前MySQL用户。它是user()函数的同义词。操做系统用户一般也被称为系统用户
正如您可能已经注意到的,SYSTEM_USER权限与SYSTEM_USER()或操做系统用户都没有关联。咱们将权限命名为‘SYSTEM_USER’,由于它恰当地描述了目的。
在这篇博文中,咱们了解了SYSTEM_USER权限的目的以及它是如何工做的。在下一篇博客文章中,咱们将更深刻地研究如何在数据库对象上建立部分撤销,以防止直接修改MySQL模式中的用户。
在本系列的最后一篇博客文章中,咱们将把各个部分放在一块儿,为一个应用程序建立多个用户。
谢谢你使用MySQL!
翻译原文:The SYSTEM_USER Dynamic Privilege | MySQL Server Blog
推荐资料扩展: