MySQL?中的權(quán)限管理及驗(yàn)證流程
引言
某天,女朋友突然問(wèn)你:“還有多少私房錢(qián)?”這個(gè)時(shí)候驚恐的你該怎么辦呢?直接把余額給她看?顯然很不符合我們的性格;如果這個(gè)時(shí)候能有一個(gè)臨時(shí)的支付寶賬號(hào),讓她看不到真實(shí)的余額該有多好??!
這樣的賬號(hào)就涉及到了數(shù)據(jù)庫(kù)的權(quán)限問(wèn)題,下面我們一起來(lái)討論一下 MySQL 中的權(quán)限管理。
權(quán)限的驗(yàn)證流程
通常,我們提及數(shù)據(jù)庫(kù)中的權(quán)限的時(shí)候,我們想到的可能是 MySQL 數(shù)據(jù)庫(kù)中的 user 表。但是,我想告訴你的是 MySQL 數(shù)據(jù)庫(kù)中的權(quán)限驗(yàn)證不僅僅只有一個(gè) user 表這么簡(jiǎn)單,我們可以通過(guò)下圖深入了解一下 MySQL 數(shù)據(jù)庫(kù)的認(rèn)證體系。
通過(guò)上圖,我們可以清晰地看到,MySQL 數(shù)據(jù)的權(quán)限認(rèn)證過(guò)程并不是只有一個(gè) user 表在起作用。
第一層:用戶(hù)登錄
在用戶(hù)登錄 MySQL 數(shù)據(jù)庫(kù)的時(shí)候,首先會(huì)將用戶(hù)輸入的用戶(hù)名密碼以及 Host 跟 mysql 數(shù)據(jù)庫(kù)中的 user 表中的 Host、User 以及 Password 三個(gè)字段相匹配,這一步是判斷用戶(hù)是否擁有登錄權(quán)限。
如果匹配不成功,將會(huì)報(bào)一個(gè) ERROR 1045 (28000): Access denied for user 'xiaoyang'@'localhost' (using password: YES) 錯(cuò)誤。一旦 MySQL 認(rèn)為用戶(hù)沒(méi)有登錄權(quán)限,將會(huì)直接拒絕登錄。
[root@dxd ~]# mysql -uxiaoyang -pxiaoyang mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'xiaoyang'@'localhost' (using password: YES)
第二層:全局權(quán)限
當(dāng)用戶(hù)通過(guò)了第一層用戶(hù)登錄驗(yàn)證之后,將會(huì)直接在 user 表中匹配全局權(quán)限,一旦匹配成功之后就會(huì)對(duì)全局所有的數(shù)據(jù)庫(kù)都擁有相應(yīng)的權(quán)限。例如,只給 xiaoyang 這個(gè)用戶(hù)設(shè)置一個(gè)全局可讀權(quán)限,那么 xiaoyang 將擁有全局可讀權(quán)限。
使用 root 用戶(hù)創(chuàng)建 xiaoyang 用戶(hù):
創(chuàng)建一個(gè)用戶(hù),Create User創(chuàng)建的用戶(hù)默認(rèn)沒(méi)有任何權(quán)限
mysql> CREATE USER ‘xiaoyang’@’localhost’ IDENTIFIED BY ‘Xiangyang123!’;
Query OK, 0 rows affected (0.00 sec)
使用 xiaoyang 用戶(hù)測(cè)試查看權(quán)限:
mysql> select * from test01.city;
ERROR 1142 (42000): SELECT command denied to user ‘xiaoyang’@’localhost’ for table ‘city’
使用 root 用戶(hù)給 xiaoyang 用戶(hù)授權(quán):
- 將 xiaoyang 這個(gè)用戶(hù)設(shè)置一個(gè)全局可讀權(quán)限
mysql> update mysql.user set Select_priv=’Y’ where User=’xiaoyang’;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
- 刷新權(quán)限,使其生效
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
測(cè)試 xiaoyang 查看權(quán)限:
- 測(cè)試查看權(quán)限
mysql> select * from test01.city;
+——+———————+———+
| id | name | fid |
+——+———————+———+
| 1 | 徐匯區(qū) | 1 |
| 2 | 浦東新區(qū) | 1 |
| 3 | 青浦區(qū) | 1 |
+——+———————+———+
3 rows in set (0.00 sec)
通過(guò)上面的例子可以看出,當(dāng) xiaoyang 這個(gè)用戶(hù)擁有一個(gè)全局可讀權(quán)限之后,就可以查看所有數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)了。設(shè)想一下,如果 xiaoyang 這個(gè)用戶(hù)沒(méi)有全局權(quán)限,怎么辦?
第三層:數(shù)據(jù)庫(kù)級(jí)別權(quán)限
如果全局權(quán)限驗(yàn)證失敗,將會(huì)進(jìn)入數(shù)據(jù)庫(kù)級(jí)權(quán)限驗(yàn)證,這個(gè)層級(jí)的權(quán)限是設(shè)置某個(gè)用戶(hù)針對(duì)于某個(gè)數(shù)據(jù)庫(kù)的權(quán)限。例如:xiaoyang 這個(gè)用戶(hù)只允許操作 test01 這個(gè)數(shù)據(jù)庫(kù),我們來(lái)看一下它的實(shí)現(xiàn)過(guò)程。
將 xiaoyang 用戶(hù)設(shè)置 test01 數(shù)據(jù)庫(kù)的查詢(xún)權(quán)限:
- 添加查看權(quán)限(清空了其他的所有權(quán)限之后添加)
mysql> insert into mysql.db (Host,User,Select_priv,Db) values(‘localhost’, ‘xiaoyang’, ‘Y’, ‘test01’);
Query OK, 1 row affected (0.00 sec)
- 查看添加的權(quán)限
mysql> select Host,User,Select_priv,Db from mysql.db;
+—————-+———————-+——————-+——————————+
| Host | User | Select_priv | Db |
+—————-+———————-+——————-+——————————+
| localhost | xiangyang | Y | test01 |
+—————-+———————-+——————-+——————————+
3 rows in set (0.00 sec)
使用 xiaoyang 用戶(hù)查看 test01 數(shù)據(jù)中任意表的數(shù)據(jù):
- 查看test01數(shù)據(jù),有權(quán)限
mysql> select * from test01.city;
+——+———————+———+
| id | name | fid |
+——+———————+———+
| 1 | 徐匯區(qū) | 1 |
| 2 | 浦東新區(qū) | 1 |
| 3 | 青浦區(qū) | 1 |
+——+———————+———+
3 rows in set (0.00 sec)
- 查看其他數(shù)據(jù)庫(kù)的數(shù)據(jù),是沒(méi)有權(quán)限的
mysql> select * from vue.sp_goods;
ERROR 1142 (42000): SELECT command denied to user ‘xiaoyang’@’localhost’ for table ‘sp_goods’
通過(guò)這個(gè)案例,我們可以看出數(shù)據(jù)庫(kù)級(jí)別的權(quán)限只對(duì)某一個(gè)數(shù)據(jù)庫(kù)起作用,而設(shè)置數(shù)據(jù)庫(kù)級(jí)別的權(quán)限時(shí)底層操作的正是 mysql.db 數(shù)據(jù)表,也就是說(shuō)在 mysql.db 數(shù)據(jù)表中設(shè)置了對(duì)應(yīng)的權(quán)限之后,該用戶(hù)將對(duì)這個(gè)數(shù)據(jù)庫(kù)中所有的數(shù)據(jù)都擁有該權(quán)限。
在實(shí)際應(yīng)用場(chǎng)景中,如果某一個(gè)用戶(hù)只允許操作某一個(gè)數(shù)據(jù)庫(kù),而其他數(shù)據(jù)庫(kù)是一個(gè)沒(méi)有權(quán)限的狀態(tài),這個(gè)時(shí)候就需要用到數(shù)據(jù)庫(kù)級(jí)權(quán)限。
如果要求只允許某個(gè)表?yè)碛袡?quán)限怎么辦呢?
第四層 :數(shù)據(jù)表級(jí)權(quán)限
數(shù)據(jù)表級(jí)權(quán)限是用來(lái)定義某個(gè)數(shù)據(jù)表的權(quán)限的,具體定義在 mysql.tables_priv 數(shù)據(jù)表中,當(dāng)數(shù)據(jù)庫(kù)級(jí)權(quán)限驗(yàn)證失敗之后就會(huì)驗(yàn)證表級(jí)權(quán)限。例如:要求 xiaoyang 這個(gè)用戶(hù)只允許查看 test01 數(shù)據(jù)庫(kù)中的 city 表,這個(gè)權(quán)限的實(shí)現(xiàn)具體如下。
將 xiaoyang 用戶(hù)設(shè)置 test01 數(shù)據(jù)庫(kù)中 city 數(shù)據(jù)表的查詢(xún)權(quán)限:
- 增加數(shù)據(jù)表級(jí)權(quán)限(其他權(quán)限全部清除)
mysql> INSERT INTO mysql.tables_priv (Host, Db, User, Table_name, Table_priv) VALUES (‘localhost’, ‘test01’, ‘xiaoyang’, ‘city’, ‘Select’);
Query OK, 1 row affected (0.00 sec)
使用 xiaoyang 用戶(hù)查詢(xún) test01 數(shù)據(jù)庫(kù)中 city 數(shù)據(jù)表的數(shù)據(jù):
- 查看 test01 數(shù)據(jù)庫(kù)中 city 數(shù)據(jù)表有權(quán)限
mysql> select * from test01.city;
+——+———————+———+
| id | name | fid |
+——+———————+———+
| 1 | 徐匯區(qū) | 1 |
| 2 | 浦東新區(qū) | 1 |
| 3 | 青浦區(qū) | 1 |
+——+———————+———+
3 rows in set (0.00 sec)
- 查看其他相同數(shù)據(jù)庫(kù)中其他表是沒(méi)有權(quán)限的
mysql> select * from test01.info;
ERROR 1142 (42000): SELECT command denied to user ‘xiaoyang’@’localhost’ for table ‘info’
通過(guò)這個(gè)案例,我們可以了解到的是 mysql.tables_priv 數(shù)據(jù)表主要是用來(lái)針對(duì)某一個(gè)數(shù)據(jù)表來(lái)設(shè)置權(quán)限的。它比數(shù)據(jù)庫(kù)級(jí)權(quán)限更加地精細(xì)化。
在實(shí)際應(yīng)用場(chǎng)景中,如現(xiàn)在有一個(gè)訪客瀏覽記錄表,一般要求只允許查看和添加,不允許有其他修改操作;還有例如訂單數(shù)據(jù)表,一般只允許添加、查看和修改,不允許刪除等應(yīng)用場(chǎng)景,數(shù)據(jù)表級(jí)權(quán)限有著不可替代的作用。
再試想一下,如果想要 xiaoyang 用戶(hù)對(duì)訂單數(shù)據(jù)表中的余額字段只能查看,又該如何呢?
第五層:字段級(jí)權(quán)限
字段級(jí)權(quán)限控制的主要是某一個(gè)字段的操作權(quán)限,當(dāng)數(shù)據(jù)庫(kù)需要針對(duì)某個(gè)具體的字段做權(quán)限控制之時(shí),就需要使用字段級(jí)權(quán)限(注意:設(shè)置字段級(jí)權(quán)限的數(shù)據(jù)表在 mysql.columns_priv 數(shù)據(jù)表中,但是 mysql.tables_priv 需要首先添加 column_priv 權(quán)限才能生效)。
例如:要求 xiaoyang 這個(gè)用戶(hù),只允許查看 sp_order 數(shù)據(jù)表中的 order_price 字段。
設(shè)置 xiaoyang 這個(gè)用戶(hù)對(duì) sp_order 數(shù)據(jù)表中的 order_price 字段的可讀權(quán)限:
- 在 mysql.tables_priv 數(shù)據(jù)表中添加字段查看權(quán)限
mysql> INSERT INTO mysql.tables_priv (Host, Db, User, Table_name, Column_priv) VALUES (‘localhost’, ‘test01’, ‘xiaoyang’, ‘sp_order’, ‘Select’);
Query OK, 1 row affected (0.00 sec)
- 在 mysql.columns_priv 中添加字段查看權(quán)限
mysql> INSERT INTO mysql.columns_priv (Host, Db, User, Table_name, Column_name, Column_priv) VALUES (‘localhost’, ‘test01’, ‘xiaoyang’, ‘sp_order’, ‘order_price’, ‘Select’);
Query OK, 1 row affected (0.00 sec)
測(cè)試該字段的可讀權(quán)限:
- 查看 order_price 字段,可以正常查看
mysql> select order_price from vue.sp_order;
+——————-+
| order_price |
+——————-+
| 222.00 |
+——————-+
27 rows in set (0.00 sec)
- 查看其他字段,沒(méi)有權(quán)限
mysql> select id from vue.sp_order;
ERROR 1143 (42000): SELECT command denied to user ‘xiaoyang’@’localhost’ for column ‘id’ in table ‘sp_order’
通過(guò)這個(gè)案例,可以看出字段級(jí)權(quán)限主要是控制某一個(gè)字段的權(quán)限。在實(shí)際應(yīng)用中,通常用來(lái)控制某個(gè)字段。例如:控制訂單表中的金額字段無(wú)法修改,而其他字段不受影響,這時(shí)就可以使用字段級(jí)權(quán)限。
第六層:對(duì)象級(jí)權(quán)限
上文中我們介紹了全局、數(shù)據(jù)庫(kù)級(jí)、數(shù)據(jù)表級(jí)以及字段級(jí)的權(quán)限,除此之外,還有一個(gè)是用來(lái)管理數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程和存儲(chǔ)函數(shù)權(quán)限的權(quán)限,及對(duì)象級(jí)權(quán)限(該權(quán)限相關(guān)的數(shù)據(jù)表是 mysql.procs_priv )。
舉個(gè)例子:超級(jí)管理員創(chuàng)建一個(gè)名為 select_city 的存儲(chǔ)過(guò)程,只給 xiaoyang 這個(gè)用戶(hù)使用該函數(shù)的權(quán)限,不給修改權(quán)限,具體操作如下。
- root 用戶(hù)創(chuàng)建存儲(chǔ)過(guò)程:
mysql> delimiter
mysql> CREATE PROCEDURE select_city(IN city_id INTEGER)
-> BEGIN
-> select * FROM city WHERE id = city_id;
-> END
mysql>CREATEPROCEDUREselect?c??ity(INcity?i??dINTEGER)
−>BEGIN
−>select∗FROMcityWHEREid=city?i??d;
−>END
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
設(shè)置 xiaoyang 用戶(hù)的權(quán)限:
mysql> use mysql;
- 增加存儲(chǔ)過(guò)程權(quán)限
mysql> INSERT INTO procs_priv (Host, Db, User, Routine_name, Routine_type, Proc_priv) VALUES (‘localhost’, ‘test01’, ‘xiaoyang’, ‘select_city’, ‘PROCEDURE’, ‘Execute’);
Query OK, 1 row affected (0.00 sec)
存儲(chǔ)過(guò)程可以正常使用:
- 選擇數(shù)據(jù)庫(kù)
mysql> use test01;
Database changed
- 使用存儲(chǔ)過(guò)程
mysql> call select_city(1);
+——+—————-+———+
| id | name | fid |
+——+—————-+———+
| 1 | 徐匯區(qū) | 1 |
+——+—————-+———+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
無(wú)法刪除存儲(chǔ)過(guò)程:
- 刪除存儲(chǔ)過(guò)程顯示無(wú)權(quán)限
mysql> DROP PROCEDURE select_city;
ERROR 1370 (42000): alter routine command denied to user ‘xiaoyang’@’localhost’ for routine ‘test01.select_city’
通過(guò)上面這個(gè)案例可以得出:mysql.procs_priv 數(shù)據(jù)表主要是用來(lái)控制存儲(chǔ)過(guò)程的權(quán)限的。
在實(shí)際應(yīng)用中,我們需要注意存儲(chǔ)過(guò)程權(quán)限一旦授予之后,自動(dòng)會(huì)將數(shù)據(jù)庫(kù)的查看權(quán)限一并授予,但是會(huì)顯示數(shù)據(jù)表為空。
mysql> use test01; Database changed mysql> show tables; Empty set (0.00 sec)
總結(jié)
數(shù)據(jù)的權(quán)限主要分為六個(gè)層級(jí):
- 第一層是登錄驗(yàn)證,驗(yàn)證失敗則立即退出;
- 第二層的權(quán)限為全局權(quán)限,這個(gè)層級(jí)的權(quán)限覆蓋整個(gè)數(shù)據(jù)庫(kù);
- 第三層的權(quán)限是數(shù)據(jù)庫(kù)級(jí)別的權(quán)限,這個(gè)層級(jí)的權(quán)限是針對(duì)于某一個(gè)數(shù)據(jù)庫(kù)的;
- 第四層級(jí)是數(shù)據(jù)表級(jí)的權(quán)限,這個(gè)層級(jí)的權(quán)限主要針對(duì)于數(shù)據(jù)表;
- 第五層權(quán)限是字段級(jí)的權(quán)限,主要針對(duì)于某一個(gè)字段的,需要注意的是字段級(jí)的權(quán)限需要依賴(lài)于第四層數(shù)據(jù)表級(jí)查看權(quán)限,沒(méi)有數(shù)據(jù)表級(jí)查看權(quán)限,字段級(jí)權(quán)限無(wú)法生效;
- 最后一個(gè)對(duì)象級(jí)權(quán)限,這個(gè)權(quán)限主要是針對(duì)于存儲(chǔ)函數(shù)和存儲(chǔ)過(guò)程的,只有擁有該權(quán)限,才能夠操作數(shù)據(jù)庫(kù)存儲(chǔ)函數(shù)或存儲(chǔ)過(guò)程。
但是,在實(shí)際應(yīng)用中,我們不需要將權(quán)限設(shè)置得過(guò)于精細(xì)化,因?yàn)檫^(guò)于精細(xì)化容易造成權(quán)限交叉并且設(shè)置權(quán)限的管理也會(huì)是相當(dāng)?shù)穆闊?/p>
以上就是MySQL 中的權(quán)限管理及驗(yàn)證流程的詳細(xì)內(nèi)容,更多關(guān)于MySQL權(quán)限管理驗(yàn)證的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
mysql簡(jiǎn)單實(shí)現(xiàn)查詢(xún)結(jié)果添加序列號(hào)的方法
這篇文章主要介紹了mysql簡(jiǎn)單實(shí)現(xiàn)查詢(xún)結(jié)果添加序列號(hào)的方法,結(jié)合實(shí)例形式演示了2種查詢(xún)結(jié)果添加序列號(hào)的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06一文帶你永久擺脫Mysql時(shí)區(qū)錯(cuò)誤問(wèn)題(idea數(shù)據(jù)庫(kù)可視化插件配置)
在MySQL啟動(dòng)時(shí)會(huì)檢查當(dāng)前系統(tǒng)的時(shí)區(qū)并根據(jù)系統(tǒng)時(shí)區(qū)設(shè)置全局參數(shù)system_time_zone的值,下面這篇文章主要給大家介紹了關(guān)于如何永久擺脫Mysql時(shí)區(qū)錯(cuò)誤問(wèn)題(idea數(shù)據(jù)庫(kù)可視化插件配置)的相關(guān)資料,需要的朋友可以參考下2022-08-08mysql數(shù)據(jù)庫(kù)找不到表的問(wèn)題及解決
這篇文章主要介紹了mysql數(shù)據(jù)庫(kù)找不到表的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Mysql?8.0解壓版下載安裝以及配置的實(shí)例教程
MySQL的安裝分為兩種,一種是安裝版本,一種是免安裝解壓版本,一般老師都會(huì)推薦免安裝解壓版本,用起來(lái)更方便些,下面這篇文章主要給大家介紹了關(guān)于Mysql?8.0解壓版下載安裝以及配置的相關(guān)資料,需要的朋友可以參考下2022-01-01