搞定linux上MySQL編程(五):MySQL權限管理

【版權聲明:尊重原創,轉載請保留出處:blog.csdn.net/shallnet,文章僅供學習交流,請勿用於商業用途】
        mysql中提供了比較完整的安全/權限管理系統,下面簡單介紹權限的原理和使用。
        mysql數據庫安裝完成啓動之後,能看當前數據庫列表可以看到一個mysql的數據庫:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| test               |
+--------------------+
該數據庫是MySQL用來存儲所有授權信息,該數據庫由若干張數據表組成,具體數據表如下:
mysql> use mysql
Database changed
mysql> show tables;
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| columns_priv              |
| db                        |
| event                     |
| func                      |
| general_log               |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| ndb_binlog_index          |
| plugin                    |
| proc                      |
| procs_priv                |
| servers                   |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+
23 rows in set (0.00 sec)
在這些數據表中,涉及全縣控制的有5張表,分別是columns_priv(爲某一張表中單個列進行訪問權限設定) 、db(對給定數據庫的所有表設定訪問權限)、host(對訪問ip地址進行權限設定)、tables_priv(對用戶的存儲過程進行權限設定)、user(用於管理MySQL的用戶)等。
在MySQL中採用兩個階段來進行權限的存取與控制,這兩個階段爲:
1.當用戶發起連接時,MySQL服務器先檢查user表,檢查方式是通過用戶名、密碼、主機的組合判斷用戶是否爲授權用戶,不是則直接拒絕。
2.若連接成功,對於提交的請求,MySQL將通過順序檢查db、host、tables_priv、columns_priv判斷是否存在訪問權限。

        在MySQL中儘量不要使用超級用戶登錄,因爲這樣很容易帶來安全隱患,比較正確的方式是設置一個超級用戶,同時設置幾個普通用戶,這樣可以分層分級來實現數據的安全管理。
        新增加用戶可以使用cerate user命令、使用grand授權、或向用戶表user中直接添加用戶記錄等方式來完成。
mysql> create user allen identified by 'allen' ; 
Query OK, 0 rows affected (0.39 sec)  <span style="font-family: 微軟雅黑;">      </span>
        查看當前所有用戶權限表:
mysql> select user,host,super_priv from user;
+------+-----------------------+------------+
| user | host                  | super_priv |
+------+-----------------------+------------+
| root | localhost             | Y          |
| root | localhost.localdomain | Y          |
| root | 127.0.0.1             | Y          |
|      | localhost             | N          |
|      | localhost.localdomain | N          |
| allen | %                     | N          |
+------+-----------------------+------------+
6 rows in set (0.00 sec)

mysql> 
        刪除用戶可以使用drop語句完成,也可以使用revoke方式、或者使用delete語句刪除user表中對於user記錄來完成同樣工作。
mysql> drop user allen;
Query OK, 0 rows affected (0.00 sec)

mysql> select user,host,super_priv from user;
+------+-----------------------+------------+
| user | host                  | super_priv |
+------+-----------------------+------------+
| root | localhost             | Y          |
| root | localhost.localdomain | Y          |
| root | 127.0.0.1             | Y          |
|      | localhost             | N          |
|      | localhost.localdomain | N          |
+------+-----------------------+------------+
5 rows in set (0.00 sec)
使用grant語句爲用戶授予權限,其格式爲:
grant priv_set on dbname to username;
其中priv_set爲權限集合,dbname是指數據庫對象,username爲用戶。

現在來看看前面創建的用戶:
[root@localhost ~]# mysql -u allen -p -h 172.27.35.8
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
......
mysql>

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db_users           |
| mysql              |
| test               |
+--------------------+
4 rows in set (0.00 sec)

mysql> usse db_users;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'usse db_users' at line 1
發現用戶allen無法使用db_users數據庫,退出登陸後使用root用戶給allen賦予所有權限。
mysql> grant all privileges on *.* to allen@localhost; 
再次使用allen登陸後:
[root@localhost ~]# mysql -u allen -p -h 172.27.35.8 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
......
mysql> use db_users;
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> 
發現可以使用數據庫了。
        事實上對於新創建的用戶,如果沒有獲得授權,是無法進行數據管理工作的。在實際應用中,grant可以執行用戶創建,也可以對多用戶在多個級別上進行權限管理,分別是,全局級、數據庫級、數據表級以及字段級。下面分別從這4個層級對grant的使用進行介紹。
1.全局權限分配,可以爲某個新建用戶分配全部操作權限,這些權限存儲在mysql.user表中,
grant all privileges on *.* to username@ '%'
該語句能授權username用戶在任意一臺主機上對數據庫服務器進行管理。雖然username擁有全部管理權限,但並沒有爲其自身分配再授予權限,所以不能爲新創建的用戶分配任何權限。以上面allen爲例:
[root@localhost ~]# mysql -u allen -p -h 172.27.35.8
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
......
mysql> create user allen_test1 identified by 'allen_test';
Query OK, 0 rows affected (0.00 sec)

mysql> grant select on *.* to allen_test1@localhost;
ERROR 1045 (28000): Access denied for user 'allen'@'%' (using password: YES)
mysql> 
如果想讓allen獲得grant的操作權限,應該這樣寫:
grant all privileges on *.* to allen@'%' with grant option;
如下:
[root@localhost ~]# mysql -u root -p
Enter password: 
......
mysql> grant all privileges on *.* to allen@'%' with grant option;
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> quit

[root@localhost ~]# mysql -u allen -p -h 172.27.35.8
Enter password: 
......
mysql> grant select on *.* to allen_test1@localhost;
Query OK, 0 rows affected (0.00 sec)
發現現在allen用戶給allen_test授權成功。

2.數據庫級權限範圍是在給定的一個數據庫中的所有目標的操作權限,這些權限會存儲在mysql.db和mysql.host中。其語法爲:
[root@localhost ~]# mysql -u root -p 
Enter password: 
......
mysql> grant all privileges on db_users.* to allen_test2@'%'  identified by 'allen'; 
Query OK, 0 rows affected (0.01 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye
然後使用allen_test2用戶登錄:
[root@localhost ~]# mysql -u allen_test2 -p -h 192.168.65.30
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
......
mysql> use db_users;
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> create table tb_test(name varchar(32), sex bool);
Query OK, 0 rows affected (0.06 sec)

mysql> insert into tb_test values ('allen', 1);
Query OK, 1 row affected (0.00 sec)

mysql> create database db_test;
ERROR 1044 (42000): Access denied for user 'allen_test2'@'%' to database 'db_test'
mysql> 
可以看到,如果執行db_users數據庫內操作是可以的,但創建一個新的數據庫就會出錯。說明數據庫級權限已經生效 。

3.數據表級權限範圍是在給定的一個數據表中所有的目標的操作權限,這些權限會存儲在mysql.tables_priv中,通常一個數據表所擁有的權限有select、insert、delete、update等。下面爲一個用戶創建一個只有select的權限:
[root@localhost ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.

mysql> grant select on db_users.* to allen_test3@'%' identified by 'allen';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye
使用用戶allen_test3用戶登錄:
[root@localhost ~]# mysql -u allen_test3 -p -h 192.168.65.30
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
mysql> select * from tb_test;
+-------+------+
| name  | sex  |
+-------+------+
| allen |    1 |
+-------+------+
1 row in set (0.00 sec)

mysql> insert into tb_test values ('Lily', 0);
ERROR 1142 (42000): INSERT command denied to user 'allen_test3'@'192.168.65.30' for table 'tb_test'
mysql> 
可見執行查詢操作是可以的,但是執行插入操作出錯。
4.字段級是在字段一級對用戶進行全線管理,設定用戶只有若干字段的某些操作權限,字段的權限信息存儲在mysql.columns_priv表中。下例對一個新用戶賦予db_users數據庫中tb_test表的sex字段查看和更新的權限。
[root@localhost ~]# mysql -u root -p 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.

mysql> grant select,update(sex) on db_users.tb_test to allen_test4@'%' identified by 'allen';
Query OK, 0 rows affected (0.01 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

mysql> quit
Bye
allen_test4用戶登錄驗證權限授予是否成功:
[root@localhost ~]# mysql -u allen_test4 -p -h 192.168.65.26
Enter password: 
......
mysql> use db_users;
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> select * from tb_test;
+-------+------+
| name  | sex  |
+-------+------+
| allen |    1 |
+-------+------+
1 row in set (0.00 sec)

mysql> update tb_test set sex=0 where name='allen';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from tb_test;
+-------+------+
| name  | sex  |
+-------+------+
| allen |    0 |
+-------+------+
1 row in set (0.00 sec)

mysql> update tb_test set name='allen_new';
ERROR 1143 (42000): UPDATE command denied to user 'allen_test4'@'192.168.65.26' for column 'name' in table 'tb_test'
mysql>
可以看到select權限沒有問題,也可以對sex字段進行更新操作。但是更新name字段報錯,因爲沒有授予其權限。
使用show grants可以查看用戶已經獲得的權限,查看自己的操作權限使用show grants命令可以查看自身權限,使用show grants for username可以查看用戶username的權限。下例爲查看root用戶自身和查看allen_test4的操作權限:
[root@localhost ~]# mysql -u root -p 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
......
mysql> show grants;
+----------------------------------------------------------------------------------------------------------------------------------------+
| Grants for root@localhost                                                                                                              |
+----------------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' WITH GRANT OPTION |
+----------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show grants for allen_test4;
+------------------------------------------------------------------------------------------------------------+
| Grants for allen_test4@%                                                                                   |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'allen_test4'@'%' IDENTIFIED BY PASSWORD '*C94FD2FCBF408CBBFAAB9C07FF4221D265AFB18F' |
| GRANT SELECT, UPDATE (sex) ON `db_users`.`tb_test` TO 'allen_test4'@'%'                                    |
+------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
和grant相反的操作時使用revoke操作,revoke作用是回收或者取消權限。
1.撤銷全部權限,
mysql> show  grants for allen_test2;
+------------------------------------------------------------------------------------------------------------+
| Grants for allen_test2@%                                                                                   |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'allen_test2'@'%' IDENTIFIED BY PASSWORD '*C94FD2FCBF408CBBFAAB9C07FF4221D265AFB18F' |
| GRANT ALL PRIVILEGES ON `db_users`.* TO 'allen_test2'@'%'                                                  |
+------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> revoke all privileges, grant option from allen_test2;
Query OK, 0 rows affected (0.00 sec)

mysql> show  grants for allen_test2;
+------------------------------------------------------------------------------------------------------------+
| Grants for allen_test2@%                                                                                   |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'allen_test2'@'%' IDENTIFIED BY PASSWORD '*C94FD2FCBF408CBBFAAB9C07FF4221D265AFB18F' |
+------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> 

2.撤銷表級某類權限,例如用戶allen_test3權限如下:
mysql> show  grants for allen_test3;
+------------------------------------------------------------------------------------------------------------+
| Grants for allen_test3@%                                                                                   |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'allen_test3'@'%' IDENTIFIED BY PASSWORD '*C94FD2FCBF408CBBFAAB9C07FF4221D265AFB18F' |
| GRANT SELECT ON `db_users`.* TO 'allen_test3'@'%'                                                          |
+------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> 
執行撤銷後權限如下:
mysql> revoke select on db_users.* from allen_test3;
Query OK, 0 rows affected (0.00 sec)

mysql> show  grants for allen_test3;
+------------------------------------------------------------------------------------------------------------+
| Grants for allen_test3@%                                                                                   |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'allen_test3'@'%' IDENTIFIED BY PASSWORD '*C94FD2FCBF408CBBFAAB9C07FF4221D265AFB18F' |
+------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> 
3.撤銷某字段權限,例如allen_test4權限如下:
mysql> show  grants for allen_test4;
+------------------------------------------------------------------------------------------------------------+
| Grants for allen_test4@%                                                                                   |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'allen_test4'@'%' IDENTIFIED BY PASSWORD '*C94FD2FCBF408CBBFAAB9C07FF4221D265AFB18F' |
| GRANT SELECT, UPDATE (sex) ON `db_users`.`tb_test` TO 'allen_test4'@'%'                                    |
+------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
可見用戶allen_test4擁有select和update 字段sex的權限,現在撤銷update的sex字段,如下:
mysql> revoke update(sex) on db_users.tb_test from allen_test4;
Query OK, 0 rows affected (0.00 sec)

mysql> show  grants for allen_test4;
+------------------------------------------------------------------------------------------------------------+
| Grants for allen_test4@%                                                                                   |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'allen_test4'@'%' IDENTIFIED BY PASSWORD '*C94FD2FCBF408CBBFAAB9C07FF4221D265AFB18F' |
| GRANT SELECT ON `db_users`.`tb_test` TO 'allen_test4'@'%'                                                  |
+------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> 
最後附上查看所有用戶的sql語句:
mysql> use mysql;
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> select user from user;
+-------------+
| user        |
+-------------+
| allen_test2 |
| allen_test3 |
| allen_test4 |
| root        |
|             |
| root        |
|             |
| root        |
+-------------+
權限管理就到此爲止了。
發佈了165 篇原創文章 · 獲贊 370 · 訪問量 49萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章