從3.22.11版本開始,MySQL提供了簡單的方法來管理用戶的訪問。使用MySQL提供的非標准的命令GRANT和REVOKE,你可以建立用戶並賦予其相應的權限,而不必關心它在前面提到的五個表中的存儲形式。

 

使用GRANT
GRANT命令用來建立新用戶,指定用戶口令並增加用戶權限。其格式如下:
mysql> GRANT ON
-> TO [IDENTIFIED BY ""]
-> [WITH GRANT OPTION];


 

正如你看到的,在這個命令中有許多待填的內容。讓我們逐一地對它們進行介紹,並最終給出一些例子以讓你對它們的協同工作有一個瞭解。
是一個用逗號分隔的你想要賦予的權限的清單。你可以指定的權限可以分為三種類型:
數據庫/數據表/數據列權限:
ALTER: 修改已存在的數據表(例如增加/刪除列)和索引。
CREATE: 建立新的數據庫或數據表。
DELETE: 刪除表的記錄。
DROP: 刪除數據表或數據庫。
INDEX: 建立或刪除索引。
INSERT: 增加表的記錄。
SELECT: 顯示/搜索表的記錄。
UPDATE: 修改表中已存在的記錄。
全域管理權限:
FILE: 在MySQL服務器上讀寫檔。
PROCESS: 顯示或殺死屬於其它用戶的服務線程。
RELOAD: 重載訪問控制表,刷新日誌等。
SHUTDOWN: 關閉MySQL服務。
特別的權限:
ALL: 允許做任何事(和root一樣)。
USAGE: 只允許登錄--其它什麼也不允許做。
這些權限所涉及到的MySQL的特徵,其中的一些我們至今還沒看到,而其中的絕大部分是你所熟悉的。
定義了這些權限所作用的區域。*.*意味著權限對所有數據庫和數據表有效。dbName.*意味著對名為dbName的數據庫中的所有數據表有效。dbName.tblName意味著僅對名為dbName中的名為tblName的數據表有效。你甚至還可以通過在賦予的權限後面使用圓括號中的數據列的清單以指定權限僅對這些列有效(在後面我們將看到這樣的例子)。
指定可以應用這些權限的用戶。在MySQL中,一個用戶通過它登錄的用戶名和用戶使用的計算機的主機名/IP位址來指定。這兩個值都可以使用%萬用字元(例如kevin@%將允許使用用戶名kevin從任何機器上登錄以享有你指定的權限)。
指定了用戶連接MySQL服務所用的口令。它被用方括號括起,說明IDENTIFIED BY ""在GRANT命令中是可選項。這裏指定的口令會取代用戶原來的密碼。如果沒有為一個新用戶指定口令,當他進行連接時就不需要口令。
這個命令中可選的WITH GRANT OPTION部分指定了用戶可以使用GRANT/REVOKE命令將他擁有的權限賦予其他用戶。請小心使用這項功能--雖然這個問題可能不是那麼明顯!例如,兩個都擁有這個功能的用戶可能會相互共用他們的權限,這也許不是你當初想看到的。

 

讓我們來看兩個例子。建立一個名為dbmanager的用戶,他可以使用口令managedb從server.host.net連接MySQL,並僅僅可以訪問名為db的數據庫的全部內容(並可以將此權限賦予其他用戶),這可以使用下面的GRANT命令:
mysql> GRANT ALL ON db.*
-> TO dbmanager@server.host.net
-> IDENTIFIED BY "managedb"
-> WITH GRANT OPTION;


 

現在改變這個用戶的口令為funkychicken,命令格式如下:
mysql> GRANT USAGE ON *.*
-> TO dbmanager@server.host.net
-> IDENTIFIED BY "funkychicken";
請注意我們沒有賦予任何另外的權限(the USAGE權限只能允許用戶登錄),但是用戶已經存在的權限不會被改變。

 

現在讓我們建立一個新的名為jessica的用戶,他可以從host.net域的任意機器連接到MySQL。他可以更新數據庫中用戶的姓名和email位址,但是不需要查閱其它數據庫的資訊。也就是說他對db數據庫具有只讀的權限(例如,SELECT),但是他可以對Users表的name列和email列執行UPDATE操作。命令如下:
mysql> GRANT SELECT ON db.*
-> TO jessica@%.host.net
-> IDENTIFIED BY "jessrules";
mysql> GRANT UPDATE (name,email) ON db.Users
-> TO jessica@%.host.net;
請注意在第一個命令中我們在指定Jessica可以用來連接的主機名時使用了%(萬用字元)符號。此外,我們也沒有給他向其他用戶傳遞他的權限的能力,因為我們在命令的最後沒有帶上WITH GRANT OPTION。第二個命令示範了如何通過在賦予的權限後面的圓括號中用逗號分隔的列的清單對特定的數據列賦予權限。

 

使用REVOKE
正如你所預期的那樣,REVOKE命令是用來去除一個用戶以前被賦予的權限的。命令的語法如下:
mysql> REVOKE [()]
-> ON FROM ;


 

這個命令中各部分的功能和在上面的GRANT命令中時一樣。要去除Jessica的合作者的DROP權限(例如,如果他經常錯誤地刪除數據庫和表),你可以使用下面的命令:
mysql> REVOKE DROP ON *.* FROM idiot@%.host.net;

 

去除一個用戶的登錄權限大概是唯一不能使用REVOKE的。REVOKE ALL ON *.*會去除用戶的所有權限,但是他還可以登錄,要完全地刪除一個用戶,你需要在user表中刪除相應的記錄:
mysql> DELETE FROM user
-> WHERE User="idiot" AND Host="%.host.net";



 

訪問控制技巧
由於MySQL中訪問控制系統工作的方法的影響,在建立你的用戶之前你必須知道兩個特徵。
當建立的用戶只能從MySQL服務運行的計算機上登錄到MySQL服務(也就是說,你需要他們telnet到服務器並在那裏運行MySQL的客戶端程式,或者是使用象PHP這樣的服務器端腳本語言進行通信),你大概會問自己GRANT命令的部分應該填什麼內容。如果服務是運行在www.host.net。你是應該將用戶設置為username@www.host.net還是username@localhost呢?

 

答案是,你不能依賴其中的任何一種來處理任何連接。從理論上來說,如果用戶在連接時(無論是使用mysql客戶端還是使用PHP的mysql_connect函數)指定了主機名,這個主機名必須與訪問控制系統中的記錄匹配。但是因為你也許不想強迫你的用戶指定主機名(事實上,mysql客戶端的用戶也許根本不會指定主機名),你最好使用下面這種工作環境。

 

對於用戶需要能夠從MySQL服務在其上運行的機器上連接MySQL的情況,在MySQL訪問控制系統中建立兩個用戶記錄:一個使用實際的主機名(例如,username@www.host.net),另一個使用localhost(例如,username@localhost),當然,你需要為兩個用戶分別grant/revoke所有的權限。

 

MySQL管理者所要面對的另一個帶有普通性的問題是一個其中的主機名使用了萬用字元的用戶記錄(例如,前面提到jessica@%.host.net)沒起作用。發生這種情況,一般是由於MySQL訪問控制系統中記錄的優先級的問題。具體地說,越具體的主機名優先級越高(例如,www.host.net是最具體的,%.host.net是比較具體的,而%是最不具體的)。

 

在一個新安裝後,MySQL訪問控制系統包含兩個匿名用戶記錄(它允許在當前主機上使用任何用戶名進行連接--這兩個記錄分別支援從localhost連接以及從服務器的實現的主機名進行連接),以及兩個root用戶目錄。我們上面討論的情況發生時是由於匿名用戶目錄的優先級比我們的新記錄高,因為他們的主機名更具體。
讓我們看看www.host.net上user表的內容,我們假定已經添加了Jessica的記錄。數據行是按照MySQL服務在確認連接時的優先級排列的:



 

正如你看到的,因為Jessica的記錄的主機名最不具體,它的優先級最低。當Jessica試圖從www.host.net連接時,MySQL服務將他的連接匹配為一個匿名用戶記錄(空白的User值與任何人匹配)。因為這些匿名記錄不需要口令,而也許Jessica輸入了他的口令,MySQL將拒絕這個連接。即使Jessica沒有輸入口令,他可能也只被給予了匿名用戶的權限(非常有限),而不是他原來被賦予的權限。
解決這個問題的方法是,要麼你刪除匿名用戶的記錄(DELETE FROM user WHERE User=""),要麼再為所有的可能從localhost連接的用戶指定兩條記錄(例如,相對於localhost以及相對於服務器的實際主機名)

 

因為要為每個用戶維護三個用戶記錄(以及相應的三套權限)會很麻煩,所以我們推薦你刪除匿名用戶,除非你需要用他們來完成什麼特殊的應用
 
 
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()