MySQL權限系統的工作原理
MySQL權限系統通過下面兩個階段進行認證:
(1)對連接配接的使用者進行身份認證,合法的使用者通過認證,不合法的使用者拒絕連接配接;
(2)對通過認證的合法使用者賦予相應的權限,使用者可以在這些權限範圍内對資料庫做相應的操作。
對于身份的認證,MySQL是通過IP位址和使用者名聯合進行确認的,例如MySQL安裝後預設建立的使用者root@localhost表示使用者root隻能從本地(localhost)進行連接配接才可以通過認證,此使用者從其他任何主機對資料庫進行的連接配接都将被拒絕。也就是說,同樣的一個使用者名,如果來自不同的IP位址,則MySQL将其視為不同的使用者。
MySQL的權限表在資料庫啟動的時候就載入記憶體,當使用者通過身份認證後,就在記憶體中進行相應權限的存取,這樣,此使用者就可以在資料庫中做權限範圍内的各種操作了。是以在對使用者做了修改操作後flush privileges;後才會生效。
在權限存取的兩個過程中,系統會用到“mysql”資料庫(安裝MySQL時被建立,資料庫名稱叫“mysql”)中user、host和db這3個最重要的權限表。在這3個表中,最重要的表是user表,其次是db表,host表在大多數情況下并不使用。user中的列主要分為4個部分:使用者列、權限列、安全列和資源控制列。
當使用者進行連接配接的時候,權限表的存取過程有以下兩個階段。
先從user表中的host、user和password這3個字段中判斷連接配接的IP、使用者名和密碼是否存在于表中,如果存在,則通過身份驗證,否則拒絕連接配接。
如果通過身份驗證,則按照以下權限表的順序得到資料庫權限:user->db->tables_priv->columns_priv。
在這幾個權限表中,權限範圍依次遞減,全局權限覆寫局部權限。
Host值可以是主機名或IP号,或“localhost”指出本地主機。
可以在Host列值使用通配符字元“%”和“_”。
Host值“%”比對任何主機名,空Host值等價于“%”。它們的含義與LIKE操作符的模式比對操作相同。例如,“%”的Host值與所有主機名比對,而“%.mysql.com”比對mysql.com域的所有主機。
如果權限表中的host既有“thomas.loc.gov”,又有“%”,而此時,連接配接從主機thomas.loc.gov過來。顯然,user表裡面這兩條記錄都符合比對條件,那系統會選擇哪一個呢?
如果有多個比對,伺服器必須選擇使用哪個條目。按照下述原則來解決:
l 伺服器在啟動時讀入user表後進行排序;
l 然後當使用者試圖連接配接時,以排序的順序浏覽條目;
l 伺服器使用與用戶端和使用者名比對的第一行。
當伺服器讀取表時,它首先以最具體的Host值排序。主機名和IP号是最具體的。“%”意味着“任何主機”并且是最不特定的。有相同Host值的條目首先以最具體的User值排序(空User值意味着“任何使用者”并且是最不特定的)。
<code>排序前:</code>
<code> </code><code>+</code><code>-----------+----------+-</code>
<code>| Host | </code><code>User</code> <code>| …</code>
<code>+</code><code>-----------+----------+-</code>
<code>|% | root | …</code>
<code>|% | jeffrey | …</code>
<code>|localhost | root | …</code>
<code>|localhost | | …</code>
<code>排序後:</code>
<code> </code>
<code>|Host | </code><code>User</code> <code>| …</code>
<code>|localhost | root | … ...</code>
<code>|localhost | | …...</code>
<code>|% |jeffrey | … ...</code>
<code>|% |root | … ...</code>
删除匿名使用者:
mysql版本5.6.18
檢視使用者
<code>mysql> </code><code>select</code> <code>user</code><code>,host,plugin,</code><code>password</code><code>,authentication_string,password_expired </code><code>from</code> <code>mysql.</code><code>user</code><code>;</code>
<code>+</code><code>------+-----------+-----------------------+-------------------------------------------+-----------------------+------------------+</code>
<code>| </code><code>user</code> <code>| host | plugin | </code><code>password</code> <code>| authentication_string | password_expired |</code>
<code>| root | localhost | | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | N |</code>
<code>| root | rhel7 | | | | N |</code>
<code>| root | 127.0.0.1 | | | | N |</code>
<code>| root | ::1 | | | | N |</code>
<code>| | localhost | | | </code><code>NULL</code> <code>| N |</code>
<code>| | rhel7 | | | </code><code>NULL</code> <code>| N |</code>
<code>| zx | % | mysql_native_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | N |</code>
使用不存在的使用者也可以登入MySQL
<code>[root@rhel7 mysql5.6.18]</code><code># ./bin/mysql -ua</code>
<code>Welcome to the MySQL monitor. Commands end with ; or \g.</code>
<code>Your MySQL connection </code><code>id</code> <code>is 16</code>
<code>Server version: 5.6.18-enterprise-commercial-advanced MySQL Enterprise Server - Advanced Edition (Commercial)</code>
<code>Copyright (c) 2000, 2014, Oracle and</code><code>/or</code> <code>its affiliates. All rights reserved.</code>
<code>Oracle is a registered trademark of Oracle Corporation and</code><code>/or</code> <code>its</code>
<code>affiliates. Other names may be trademarks of their respective</code>
<code>owners.</code>
<code>Type </code><code>'help;'</code> <code>or </code><code>'\h'</code> <code>for</code> <code>help. Type </code><code>'\c'</code> <code>to </code><code>clear</code> <code>the current input statement.</code>
<code>mysql></code>
删除user為空的使用者
<code>mysql> </code><code>delete</code> <code>from</code> <code>mysql.</code><code>user</code> <code>where</code> <code>user</code><code>=</code><code>''</code><code>;</code>
<code>Query OK, 2 </code><code>rows</code> <code>affected (0.00 sec)</code>
<code>mysql> flush </code><code>privileges</code><code>;</code>
<code>Query OK, 0 </code><code>rows</code> <code>affected (0.00 sec)</code>
<code>5 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>
使用不存在的使用者不能再登入MySQL
<code>[root@rhel7 mysql5.6.18]# ./bin/mysql -ua</code>
<code>ERROR 1045 (28000): Access denied </code><code>for</code> <code>user</code> <code>'a'</code><code>@</code><code>'localhost'</code> <code>(using </code><code>password</code><code>: </code><code>NO</code><code>)</code>
參考:《深入淺出MySQL》
本文轉自hbxztc 51CTO部落格,原文連結:http://blog.51cto.com/hbxztc/1879606,如需轉載請自行聯系原作者