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操作以確保設置生效。