MySQL8.0角色管理—(二)
- 2020 年 2 月 25 日
- 筆記
//
MySQL8.0角色管理—(二)
//
昨天介绍了MySQL8.0中角色的概念,简单讲了角色的部分操作,今天来看看角色管理部分的关键内容。
01
创建角色
新创建的角色暂时是被锁定的,没有密码。该角色的属性可以被拥有create user权限的用户来修改。处于锁定状态下的账号,不能被用来对服务器进行验证,也就是无法直接登录服务器,解锁之后的角色,就可以登录服务器了。
昨天的文章中,我们创建了两个角色,并将角色分配给两个账号,如下:
角色:role_ro
权限:select
账号:yeyz_ro
角色2:role_rw
权限:select,update,insert,delete
账号:yeyz_rw
当我们使用yeyz_ro的账号去登录数据库的时候,可以发现:
1、账号可以登录
2、无法执行任何查询操作,甚至连我们的数据库yeyz都看不到。
如下:
192:~ root# /usr/local/mysql_8.0/bin/mysql -uyeyz_ro -pyeyz -h127.0.0.1 --socket=/data/mysql_5306/tmp/mysql.sock --port=5306 ........ Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | +--------------------+ 1 row in set (0.01 sec) mysql> use yeyz; ERROR 1044 (42000): Access denied for user 'yeyz_ro'@'%' to database 'yeyz'
这个原因是由于当前没有角色被"激活"导致的,如下:
mysql> select current_role(); +----------------+ | current_role() | +----------------+ | NONE | +----------------+ 1 row in set (0.00 sec)
那么如何"激活"角色呢?
02
如何激活角色?
使用set default role语法可以激活用户进行身份认证时所需的角色,具体的方法如下:
mysql> set default role 'role_ro' to yeyz_ro@'%'; Query OK, 0 rows affected (0.00 sec)
将role_ro这个角色设置为yeyz_ro的默认激活角色,这样,就可以使用yeyz_ro的用户来访问对应的数据库了,该用户将拥有role_ro这个角色的权限。如下,再次用yeyz_ro登录MySQL服务,查看当前的角色:
mysql> select current_role(); +----------------+ | current_role() | +----------------+ | `role_ro`@`%` | +----------------+ 1 row in set (0.00 sec)
进行相关操作,
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | yeyz | +--------------------+ 5 rows in set (0.00 sec) mysql> use yeyz; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------+ | Tables_in_yeyz | +----------------+ | test_tbl0 | +----------------+ 1 row in set (0.00 sec) mysql> select * from test_tbl0; +------+----------+ | id | name | +------+----------+ | 1 | zhangsan | | 2 | lisi | | 3 | wangwu | +------+----------+ 3 rows in set (0.00 sec)
如果我们进行delete操作,则会报错,因为role_ro只有select权限。
mysql> delete from yeyz.test_tbl0; ERROR 1142 (42000): DELETE command denied to user 'yeyz_ro'@'127.0.0.1' for table 'test_tbl0' mysql>
这种"激活"角色的方法可以让用户拥有角色所拥有的权限,但是不难看出来,每次给新建用户绑定一个角色,在新建用户登录之前,都得将该用户激活一下,从操作上看不是特别方便,如何让所有的指定的角色都即时生效呢?
MySQL提供了一个系统参数来解决这个问题,该参数是:
mysql> show variables like '%activate%'; +-----------------------------+-------+ | Variable_name | Value | +-----------------------------+-------+ | activate_all_roles_on_login | OFF | +-----------------------------+-------+ 1 row in set (0.00 sec)
该参数是默认关闭的,直接打开即可。
03
多个角色之间如何切换?
我们知道,当我们创建一个用户的时候,可以给它绑定多个角色,那么如何在多个角色之间进行切换,我们一把。
首先,创建账号yeyz_ro_and_rw,并将上面的role_ro和role_rw两个角色绑定在该用户上,并指定role_ro为默认角色:
mysql> create user yeyz_ro_and_rw@'%' identified by 'yeyz'; Query OK, 0 rows affected (0.02 sec) mysql> grant 'role_ro' to yeyz_ro_and_rw@'%'; Query OK, 0 rows affected (0.00 sec) mysql> grant 'role_rw' to yeyz_ro_and_rw@'%'; Query OK, 0 rows affected (0.00 sec) mysql> set default role 'role_ro' to yeyz_ro_and_rw@'%'; Query OK, 0 rows affected (0.00 sec) mysql> exit Bye 192:~ root# /usr/local/mysql_8.0/bin/mysql -uyeyz_ro_and_rw -pyeyz -h127.0.0.1 --socket=/data/mysql_5306/tmp/mysql.sock --port=5306 ... mysql> use yeyz; Database changed mysql> select * from test_tbl0; +------+----------+ | id | name | +------+----------+ | 1 | zhangsan | | 2 | lisi | | 3 | wangwu | +------+----------+ 3 rows in set (0.00 sec) mysql> insert into test_tbl0 values (4,'zhaoliu'); ERROR 1142 (42000): INSERT command denied to user 'yeyz_ro_and_rw'@'127.0.0.1' for table 'test_tbl0' mysql>
可以看到,role_ro拥有select的权限,所以账号yeyz_ro_and_rw可以对yeyz数据库下面的表test_tbl0进行select操作,但是执行insert操作的时候报错。也容易理解,因为角色role_ro没有insert权限。
此时将用户的角色切换成role_rw,再次执行:
mysql> insert into test_tbl0 values (4,'zhaoliu'); ERROR 1142 (42000): INSERT command denied to user 'yeyz_ro_and_rw'@'127.0.0.1' for table 'test_tbl0' mysql> select current_role(); +----------------+ | current_role() | +----------------+ | `role_ro`@`%` | +----------------+ 1 row in set (0.00 sec) mysql> set role 'role_rw'; Query OK, 0 rows affected (0.00 sec) mysql> insert into test_tbl0 values (4,'zhaoliu'); Query OK, 1 row affected (0.01 sec) mysql> select current_role(); +----------------+ | current_role() | +----------------+ | `role_rw`@`%` | +----------------+ 1 row in set (0.00 sec)
可以看到,再次执行insert操作的时候,执行成功了,原因是将角色切换到了role_rw,而role_rw拥有insert权限。
04
强制角色定义
强制角色,顾名思义,就是用户账号强制绑定的一个角色,如果我们在创建用户的时候,想要给用户赋予一定的权限,那么可以通过设置一个强制角色,来给所有新生成的用户都赋予这个角色的权限。强制角色一般是需要定义在my.cnf文件中的,假设我们要定义一个强制角色,拥有对yeyz库的select权限,有两种方法:
第一种是可以在配置文件中写下:
[mysqld] mandatory_roles='role_ro'
这样,所有新创建的账号就有了该角色的权限。
第二种是运行过程中输入下面命令:
set persist mandatory_roles = 'role_ro';
这样,强制角色就永久生效了。
有以下几点需要注意
1、这里的永久生效,是指即使MySQL服务器重启了,那么该配置也会生效。相当于改了my.cnf配置文件,需要区别于MySQL5.7版本的set global语法。
2、强制角色也需要使用set default role的方法进行"角色激活",或者通过修改参数activate_all_roles_on_login的方法进行"激活"才可以生效。
3、强制角色不能通过revoke的方法或者drop的语法进行权限回收或者角色删除
4、不能将包含system_user权限的角色列在强制角色列表中。
5、如果只是在配置文件中指定了角色为强制角色,但是实际上该角色不存在于mysql.user表里面,则后续创建的账号不会继承该角色的权限。如果后续人工在MySQL实例中对强制角色进行了补充,则需要进行flush privileges操作以确保设置生效。