MySQL授權系統主要通過五個表(user、db、host、tables_priv和columns_priv)來實現,其中用於訪問數據庫的各種用戶信息都保存在mysql庫的user表中。賬戶權限信息被存儲在mysql數據庫的user、db、host、tables_priv、columns_priv和procs_priv表中。
user表——該表決定是否允許用戶連接到服務器。如果允許連接,權限字段則為該用戶的全局權限。
db表——用於決定哪些用戶可以從哪些主機訪問哪些數據庫。包含在db表中的權限適用於這個表標識的數據庫。
host表——當您想在db表的范圍之內擴展一個條目時,就會用到這個表。舉例來說,如果某個db允許通過多個主機訪問的話,那么超級用戶就可以讓db表內將host列為空,然后用必要的主機名填充host表。
tables_priv表——該表與db表相似,不同之處是它用於表而不是數據庫。這個表還包含一個其他字段類型,包括timestamp和grantor兩個字段,用於存儲時間戳和授權方。在本文后面我們會對這個表做進一步的講解。
columns_priv——該表作用幾乎與db和tables_priv表一樣,不同之處是它提供的是針對某些表的特定列的權限。
權限表的存取過程是:
1) 先從user表中的host、 user、 password這3個字段中判斷連接的IP、用戶名、密碼是否存在表中,存在則通過身份驗證;
2) 通過權限驗證,進行權限分配時,按照user、db、tables_priv、columns_priv的順序進行分配。即先檢查全局權限表 user,如果user中對應的權限為Y,則此用戶對所有數據庫的權限都為Y,將不再檢查db, tables_priv,columns_priv;如果為N,則到db表中檢查此用戶對應的具體數據庫,並得到db中為Y的權限;如果db中為N,則檢 查tables_priv中此數據庫對應的具體表,取得表中的權限Y,以此類推。
更詳細參考:http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#what-privileges
1.創建用戶
1) 可以使用CREATE USER用於創建新的MySQL賬戶, CREATE USER會在沒有權限的mysql.user表中創建一個新記錄。如果 賬戶已經存在,則出現錯誤。
CREATE USER user [IDENTIFIED BY [PASSWORD] 'password'] [, user [IDENTIFIED BY [PASSWORD] 'password']] ...
mysql>create user test1@'localhost' identified by '12345'; --test1只能本地訪問
mysql>create user test2@'%' identified by '12345'; --test2可以遠程訪問
mysql>create user test3@’172.21.78.89’ identified by ‘12345’; --test3僅從172.21.78.89上訪問
create user test3@172.21.78.89 identified by ‘12345’;
mysql>create user test4@172.21.78.% identified by ‘12345’; --test4可以從172.21.78.*網段上訪問
2) 也可以使用grant語句,GRANT語句的主要用途是來給帳戶授權的,但也可用來建立新帳戶並同時授權。
mysql>grant select,insert,update,delete on mydb.* to test1@localhost identified by "123456";
可以在hostname中指定通配符。例如user_name@'%.loc.gov'適用於在loc.gov域中的任何主機的user_name。同時user_name@'144.155.166.%'適用於144.155.166 C級子網中的任何主機的user_name。簡單形式user_name是user_name@'%'的同義詞。
3) 可以直接用INSERT語句創建相同的賬戶,然后使用FLUSH PRIVILEGES告訴服務器重載授權表。
mysql> insert into mysql.user(Host,User,Password) values("localhost","test3",password("12345"));
mysql>flush privileges;
第一種和第三種創建用戶后還需要進行授權。
2.數據庫用戶授權
GRANT權限列表 ON 庫名.表名TO 用戶名@來源地址[ IDENTIFIEDBY ‘密碼‘]
使用GRANT語句的注意事項:
■ 權限列表:用於列出授權使用的各種數據庫操作,以逗號分隔。All表示所有權限;
■ 庫名.表名:用於指定授權操作的庫和表的名稱,其中可以使用“*”。如:使用“mydb.*”表示授權操作的對象為mydb庫中的所有表。
■ 用戶名@來源地址:用於指定用戶名稱和允許訪問的客戶機地址,即誰能連接、能從哪里連接。來源的地址可以是域名、IP地址,還可以使用“%”通配符,表示某個區域或網段內的所有地址。如:“%.example.com”、“172.168.10.%”等
■ IDENTIFIED BY:設置用戶連接數據庫時所使用的密碼字符串。在新建用戶時,若省略則用戶的密碼將為空。
■ 使用GRANT語句授權的用戶記錄,會保存到mysql庫的user、db、host、tables_priv等。
例:添加一個名為test1的數據庫用戶,並允許其從本機訪問,對mydb庫中的所有表具有查詢權限,驗證密碼為“12345”。
mysql> GRANT select ON mydb.* TO 'test1'@'localhost' IDENTIFIED BY '12345';
例:增加一個test2用戶,密碼為12345,可以在任何主機上登錄,並對所有數據庫有查詢,增加,修改和刪除的功能。
mysql>grant select, insert, update, delete on *.* to test2@'%' identified by '12345';
例:增加一個test3用戶,密碼為12345,只能在172.21.78.89上登錄,並對mydb數據庫有查詢,增加,修改和刪除的功能。
mysql>grant select, insert, update, delete on mydb.* to test3@172.21.78.89 identified by '12345';
例:授權用戶test4擁有數據庫mydb的所有權限
mysql>grant all privileges on mydb.* to test4@localhost identified by '12345';
例:創建一個只允許從本地登錄的超級用戶test5,並允許將權限賦予別的用戶,密碼為12345
mysql>GRANT ALL PRIVILEGES ON *.* TO test5@localhost IDENTIFIED BY '12345' WITH GRANT OPTION;
例:創建一個一般應用程序用戶,並只需要SELECT, INSERT, UPDATE, DELETE, CREATE TEMPORARY TABLES等權限,如有存儲過程還需要加上EXECUTE權限。指定登錄網段172.21.78網段。
mysql>GRANT USAGE,SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ,CREATE TEMPORARY TABLES,EXECUTE ON mydb.* TO test6@'172.21.78.%' IDENTIFIED BY '12345';
例:創建一個普通用戶(僅有查詢權限)
mysql>GRANT USAGE,SELECT ON mydb.* TO test7@'172.21.78.%' IDENTIFIED BY '12345';
3.查看用戶權限
查看服務器庫中所有用戶列表(因為用戶信息保存在mysql.user表中,故可從該表中查看)
mysql> select distinct concat('user:',user,'@',host,':') as query from mysql.user;
+---------------------------+
| query |
+---------------------------+
| user:test1@%: |
| user:test2@%: |
| user:test3@172.21.78.89: |
| user:test4@172.21.78.%: |
| user:test5@172.21.78.89: |
| user:root@localhost: |
| user:test1@localhost: |
| user:test2@localhost: |
+---------------------------+
8 rows in set (0.59 sec)
或者使用 select * from mysql.user 可看到相關權限等信息。
查看當前登陸用戶
mysql> select user();
+----------------+
| user() |
+----------------+
| test2@localhost |
+----------------+
1 row in set (0.00 sec)
USER()或SYSTEM_USER() 返回當前登陸用戶名
SESSION_USER() 和 USER() 具有相同的意義
SYSTEM_USER() 和 USER() 具有相同的意義
CURRENT_USER, CURRENT_USER() 返回當前會話被驗證的用戶名和主機名組合
mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| test2@localhost |
+----------------+
1 row in set (0.00 sec)
查看權限:
SHOW GRANTS 語句: SHOWGRANTSFOR 用戶名@來源地址
例:mysql> show grants for test1;
+------------------------------------------------------------------------------------------------------------------------------+
| Grants for test1@% |
+------------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'test1'@'%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |
+------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> show grants for test2;
+------------------------------------------------------------------------------------------------------+
| Grants for test2@% |
+------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test2'@'%' IDENTIFIED BY PASSWORD '*00A51F3F48415C7D4E8908980D443C29C69B60C9' |
+------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
例:查看用戶test5從主機172.21.78.89訪問數據庫時得授權信息。
mysql> show grants for test5@172.21.78.89;
+-----------------------------------------------------------------------------------------------------------------+
| Grants for test5@172.21.78.89 |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test5'@'172.21.78.89' IDENTIFIED BY PASSWORD '*00A51F3F
48415C7D4E8908980D443C29C69B60C9' |
+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
注意:使用show grants for test5查看不到相關信息。
mysql> show grants for test5;
ERROR 1141 (42000): There is no such grant defined for user 'test5' on host '%'
4.撤銷權限:
REVOKE 語句:用於撤銷指定用戶的數據庫權限,撤銷權限后的用戶仍然可以連接到mysql服務器,但將禁止執行對應的數據庫操作:
格式:REVOKE權限列表ON 數據庫名.表名FROM用戶名@來源地址
如:撤銷用戶test5從172.21.78.89訪問數據庫的所有權限:
mysql> revoke all on *.* from test5@172.21.78.89;
Query OK, 0 rows affected (0.00 sec)
5.刷新權限
當mysqld服務器啟動時,將授權表的內容讀入到內存中。你可以通過FLUSH PRIVILEGES語句或執行mysqladmin flush-privileges或mysqladmin reload命令讓它重新讀取表。
Flush privileges使權限生效,尤其在對那些權限表user、db、host等做了update或者delete更新的時候。
mysql>FLUSH PRIVILEGES;
6.修改用戶密碼
可以使用mysqladmin工具,格式:mysqladmin -u用戶名 -p舊密碼 password 新密碼
例:給root加個密碼ab12。首先在DOS下進入目錄mysqlbin,然后鍵入以下命令:
mysqladmin -uroot -password 12345
注:因為開始時root沒有密碼,所以-p舊密碼一項就可以省略了。
再將root的密碼改為abcde。
mysqladmin -uroot -12345 password abcde
例: mysqladmin -utest2 -p12345 password public12
注意,需要相關的權限
也可使用update語句更新:
mysql>update mysql.user set password=password('123456') where User='test1' and Host='localhost';
mysql>flush privileges;
還可使用SET PASSWORD命令,
mysql> SET PASSWORD FOR 'USERNAME'@'HOST'=PASSWORD('NEW_PASSWORD'
如修改test1 密碼
mysql> set password for test1@localhost = password('public12');
Query OK, 0 rows affected (0.00 sec)
7.刪除用戶
mysql>delete from user where user='test2' and host='localhost';
mysql>flush privileges;
注意刪除用戶最好不要使用DELETE直接刪除,因為使用DELETE刪除后用戶的權限並未刪除,新建同名用戶后又會繼承以前的權限。
正確的做法是使用DROP USER命令刪除用戶,比如要刪除'test'@'172.168.100.%'用戶采用如下命令:
mysql>DROP USER test3@'172.21.78.89’; ---- 刪除賬戶及權限