首页
学习
活动
专区
圈层
工具
发布

MySQL8.0角色管理---(二)

//

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都看不到。

如下:

代码语言:javascript
复制
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'

这个原因是由于当前没有角色被"激活"导致的,如下:

代码语言:javascript
复制
mysql> select current_role();
+----------------+
| current_role() |
+----------------+
| NONE           |
+----------------+
1 row in set (0.00 sec)

那么如何"激活"角色呢?

02

如何激活角色?

使用set default role语法可以激活用户进行身份认证时所需的角色,具体的方法如下:

代码语言:javascript
复制
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服务,查看当前的角色:

代码语言:javascript
复制
mysql> select current_role();
+----------------+
| current_role() |
+----------------+
| `role_ro`@`%`  |
+----------------+
1 row in set (0.00 sec)

进行相关操作,

代码语言:javascript
复制
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权限。

代码语言:javascript
复制
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提供了一个系统参数来解决这个问题,该参数是:

代码语言:javascript
复制
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为默认角色:

代码语言:javascript
复制
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,再次执行:

代码语言:javascript
复制
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权限,有两种方法:

第一种是可以在配置文件中写下:

代码语言:javascript
复制
[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操作以确保设置生效。

下一篇
举报
领券