深入學習MySQL授權表

hzczichao發表於2010-07-16
在本文中,我們將向讀者詳細介紹MySQL的授權表,並透過一些例項來講解MySQL是如何提高這些授權表來實現使用者訪問控制的。我們首先介紹MySQL訪問控制過程,然後說明tables_priv和columns_priv授權表,我們會給出與MySQL的tables_priv表有關的解釋和範例。最後,我們介紹columns_priv授權表及其範例。[@more@]

 一、MySQL授權表概述

  MySQL伺服器的特點之一是,它在控制每個使用者行為方面提供了極大的靈活性。例如,我們既可以限制使用者訪問整個資料庫,也可以限制使用者訪問資料庫中特定的表,或者禁止訪問特定表中的特定列。由此看出MySQL伺服器在使用者授權方面的靈活性。本文將向大家詳細介紹MySQL伺服器是如何處理使用者許可權的授與/撤回的,尤其是MySQL的授權表tables_priv和columns_priv。

  MySQL的授權系統通常是透過MySQL資料庫中的五個表來實現的,這些表有user、db、host、tables_priv和columns_priv。這些表的用途各有不同,但是有一點是一致的,那就是都能夠檢驗使用者要做的事情是否為被允許的。每個表的欄位都可分解為兩類,一類為作用域欄位,一類為許可權欄位。作用域欄位用來標識主機、使用者或者資料庫;而許可權欄位則用來確定對於給定主機、使用者或者資料庫來說,哪些動作是允許的。下面,我們對這些表的作用做簡單介紹:

  • user表——該表決定是否允許使用者連線到伺服器。如果允許連線,許可權欄位則為該使用者的全域性許可權。
  • db表——用於決定哪些使用者可以從哪些主機訪問哪些資料庫。包含在db表中的許可權適用於這個表標識的資料庫。
  • host表——當您想在db表的範圍之內擴充套件一個條目時,就會用到這個表。舉例來說,如果某個db允許透過多個主機訪問的話,那麼超級使用者就可以讓db表內將host列為空,然後用必要的主機名填充host表。
  • tables_priv表——該表與db表相似,不同之處是它用於表而不是資料庫。這個表還包含一個其他欄位型別,包括timestamp和grantor兩個欄位,用於儲存時間戳和授權方。在本文後面我們會對這個表做進一步的講解。
  • columns_priv——該表作用幾乎與db和tables_priv表一樣,不同之處是它提供的是針對某些表的特定列的許可權。這個表也多出了一個欄位型別,即其他欄位,包括了一個timestamp列,用於存放時間戳。 在本文後面部分,我們還會對columns_priv表做進一步的說明。

  下面,我們透過如下幾個方面對MySQL使用者授權過程加以介紹:首先介紹MySQL訪問控制過程,解答MySQL授權表是如何工作的;然後,我們介紹tables_priv和columns_priv授權表,我們會給出與MySQL的tables_priv表有關的解釋和範例。最後,我們介紹與columns_priv授權表有關的解釋和若干範例。

  二、MySQL伺服器的訪問控制

  現在讓我們來看看MySQL伺服器是如何透過使用者特權來控制使用者訪問的。雖然這乍聽起來好像挺嚇人的,但是透過一個例子的演示,您就會發現其實事情沒有我們想象的那麼難以理解。

  首先,對使用者的訪問進行控制的時候,系統需要檢視作為過濾器的一些授權表,這些表的使用過程是從一般到特殊,這些表包括:

  • User表
  • Db表
  • Host表
  • Tables_priv 表
  • Columns_priv 表

  此外,一旦連線到了伺服器,一個使用者可以使用兩種型別的請求:

  • 管理請求(shutdown,reload,等)
  • 資料庫相關的請求(insert,delete,等)

  當使用者提交管理請求時,伺服器只需檢視user表,這是因為user表是唯一包含與管理工作有關的許可權的一個表。然而,當使用者提交資料庫請求時,要檢視的表就要更多了。

  您可能已經注意到了,這些授權表的內容好像有些重複,例如user表中有select許可權,同時host和user表中也有同樣的許可權。但是,這樣做自有其道理。我們可以考慮一下user表中全域性性的與資料庫相關的許可權,也就是說,在這個表中授予使用者的許可權對伺服器上的所有資料庫都有效。這些許可權可以被認為是超級使用者許可權。相反,包含在host和db表之內的與資料庫相關的許可權則是特定於主機或者資料庫的。因此,讓這個表內所有的許可權保持為“N”不失為一個明智的選擇。

  讓我們假定我們的user和db表如下所示:

深入學習MySQL授權表

 情景1:失敗的連線嘗試

  使用者“alessia”連線伺服器時將被拒絕。因為,主機、使用者和/或密碼與保持在user表中的不匹配, 所以會拒絕使用者的請求。

  情景2:user表中資料庫許可權為N,db表中資料庫許可權為Y

  1. 使用者wj嘗試連線時將會成功。

  2. 使用者wj試圖在資料庫oats上執行Select命令。

  3. 伺服器檢視user表,對應於Select命令的條目的值為N,即表示拒絕。

  4. 伺服器然後檢視db表,對應於Select命令的表項的值為Y,即表示允許。

  5. 該請求將成功執行,因為該使用者的db表中的SELECT欄位的值為Y。

  情景3:user表中資料庫許可權為Y,db表中資料庫許可權為N

  1. 使用者wj嘗試連線時將會成功。

  2. 使用者wj試圖在資料庫oats上執行Select命令。

  3. 伺服器檢視user表,對應於Select命令的表項的值為Y,即表示允許。 因為在user表之內授與的許可權是全域性性的,所以該請求會成功執行。

  情景4:user表中資料庫許可權為N,db表中資料庫許可權為N

  1. 使用者wj嘗試連線時將會成功。

  2. 使用者wj試圖在資料庫oats上執行Select命令。

  3. 伺服器檢視user表,對應於Select命令的表項的值為N,即表示拒絕。

  4. 伺服器現在會檢視db表,對應於Select命令的表項的值為N,即表示拒絕。

  5. 伺服器現在將查詢tables_priv和columns_priv表。如果使用者的請求符合表中賦予的許可權,則准予訪問。 否則,訪問就會被拒絕。

  對於tables_priv和columns_priv表,後面會進一步加以詳述。

  情景5:讓我們假定下列情況為真:

  • user表中使用者wj的host欄位的值為%。
  • db表中使用者wj對應的host欄位的值為空。

  這時會發生什麼情況呢?

  1. 使用者wj嘗試透過一個給定主機進行連線。

  2. 假設密碼是正確的,那麼就會連線成功,因為user表指出只要是透過使用者名稱wj和有關密碼進行連線的話,任何(字元%所代表的含義)主機都是允許的。

  3. MySQL伺服器將查詢db表,不過,這裡沒有指定主機。

  4. MySQL伺服器現在將檢視host表。如果該使用者要連線的資料庫以及使用者建立連線時所在主機的名稱都位於host表中,那麼該使用者就能夠按照host表中所列出的許可權來執行命令。 否則的話,使用者將無法執行命令,實際上更本就無法連線。

  透過了解上述情形,讀者就應該對授權系統有一定了解了。下面,我們再來仔細聊聊tables_priv表和columns_priv表。

 三、Tables_priv表與columns_priv表

  在上面介紹的五種授權表中,tables_priv和columns_priv是後來加入進來的,它們的主要目的是提供細粒度的使用者控制。這兩個表與授權表db非常類似,但是其控制的範圍更加細緻,即特定資料庫中的特定的表。前面說過,超級使用者可以透過授權表db來限制使用者在一個資料庫中的行為,有了這兩個授權表,超級使用者可以進一步控制使用者針對每個表和每個欄位的動作。所以,這給超級使用者提供了更加靈活的控制選項。

  在深入學習對資料表的訪問控制之前,首先讓我們瞭解一下下列特性:

  • 萬用字元可以用於這兩個表的host欄位,但是不允許在Db、Table_name和Column_name欄位使用萬用字元。
  • 許可權欄位被宣告為SET欄位。
  • tables_priv和columns_priv表只應當透過GRANT/REVOKE命令進行修改。透過INSERT命令向這兩個表插入資料會導致伺服器不穩定!
  • tables_priv表中的table_priv欄位可以允許下列命令:Select、Insert、Update、Delete、Create、Drop、Grant、References、Index和Alter。
  • tables_priv表中的column_priv欄位允許下列命令:Select、Insert、Update和References。
  • columns_priv表中的type欄位允許下列命令:Select、Insert、Update和References。

  授權表tables_priv

  下列是一個tables_priv表的示意圖:

深入學習MySQL授權表

  下面簡要介紹各欄位的含義:

  • Host——適用於那些主機?
  • Db——適用於從上面的主機所連線的哪些資料庫?
  • User——適用於來自上述主機的哪些使用者?
  • Table_name——適用於上述資料庫中的哪些表?
  • Table_priv——為這個表賦予哪些許可權?
  • Column_priv——為這個表中的個欄位賦予哪些許可權?
  • Timestamp——這個許可權是何時賦予的?
  • Grantor——誰授與該使用者的這個許可權?
  •  要想真正弄懂tables_priv表,最好的辦法就是透過例項進行學習,下面我們就給出一些例子。

      例1:

    %>GRANT SELECT ON italy TO wj@314interactive.com;

      這條命令的作用是什麼?以上命令允許來自主機314interactive.com的使用者wj在表italy上至下一個SELECT語句。請記住,只有當給定資料庫/主機和使用者名稱對應的db或者host表中的SELECT欄位的值為N時,才需要訪問這個表。如果給定資料庫/主機和使用者名稱對應的db或者host表中的SELECT欄位中有一個值為Y的話,那麼就無需控制該tables_priv表。

      例2:

    %>GRANT SELECT, INSERT ON oats.italy TO wj@314interactive.com;

      這條命令的作用是什麼?以上命令允許來自主機314interactive.com的使用者wj對資料庫oats中的資料表italy執行SELECT和INSERT語句。

      例3:

    %>REVOKE SELECT on oats.italy from wj@314interactive.com

      這條命令的作用是什麼?以上命令撤消來自主機314interactive.com的使用者wj對資料庫oats中的表italy的執行SELECT的許可權。

      重要的是要認識到,包含在tables_priv中的資訊僅當host/db表不允許使用者執行要求的功能所需的許可權時才生效。如果給定的許可權在host/db表中為Y,那麼就無需考察tables_priv表。

      例4:

    %>GRANT SELECT(id,name,address,phone),update(address,phone) ON
    company.customers
    TO gilmore@314interactive.com;

      這條命令的作用是什麼?以上命令將授予對company資料庫中customers表內id、name、address和phone欄位執行SELECT的許可權,以及對address和phone欄位執行UPDATE的許可權。

      這將帶來哪些影響?這條命令會修改tables_priv表和columns_priv表,這是因為它引用這兩個表和表內特定的欄位。

      例5:

    %>REVOKE UPDATE(address,phone) ON company.customers FROM gilmore@314interactive.com;

      這條命令的作用是什麼?這個命令將撤消對company資料庫中customers表內的address和phone欄位執行UPDATE操作的許可權。

      這將帶來哪些影響?因為該命令直接涉及給定表中的某些欄位,所以columns_priv表以及tables_priv表也會更新。

      前面說過,只有在必須的情況下才會使用授權表,舉例來說,如果高優先順序的表提供了適當的許可權的話,那麼就無需查閱優先順序較低的授權表了。如果高優先順序的表中對應命令的值為N,那麼就需要進一步檢視低優先順序的授權表。

      四、小結

      在本文中,我們為讀者詳細介紹了MySQL的授權表,並透過一些例項來講解MySQL是如何提高這些授權表來實現使用者訪問控制的。我們首先介紹了MySQL訪問控制過程,解答了MySQL授權表是如何工作的;然後,我們介紹了tables_priv和columns_priv授權表,並提供了與MySQL的tables_priv表有關的解釋和範例。最後,我們介紹了columns_priv授權表並給出了若干範例。

無論是那種級別的許可權,只要有一個級別允許了,訪問就能成功,這樣是合理的,比如說我只想讓一個使用者訪問一個資料庫中的一個表,那麼在全域性和資料庫級訪問許可權肯定是N,只有在表級是Y。如果一個使用者在全域性是Y,那麼不管他在資料庫級和表級是不是Y,他都會訪問成功。因為只要在全域性驗證了Y,MYSQL就不再資料庫級和表級進行驗證。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23595918/viewspace-1035334/,如需轉載,請註明出處,否則將追究法律責任。

相關文章