MySQL中的賬號(hào)與權(quán)限管理
權(quán)限系統(tǒng)的工作原理
MySQL權(quán)限系統(tǒng)通過(guò)下面兩個(gè)階段進(jìn)行認(rèn)證:
- 對(duì)連接的用戶進(jìn)行身份認(rèn)證,合法的用戶通過(guò)認(rèn)證奴璃、不合法的用戶拒絕連接悉默。
- 對(duì)通過(guò)認(rèn)證的合法用戶賦予相應(yīng)的權(quán)限,用戶可以在這些權(quán)限范圍內(nèi)對(duì)數(shù)據(jù)庫(kù)做相應(yīng)的操作苟穆。
對(duì)于身份抄课,MySQL是通過(guò)IP地址
和用戶名
聯(lián)合進(jìn)行確認(rèn)的,例如MySQL安裝默認(rèn)創(chuàng)建的用戶root@localhost
表示用戶root只能從本地(localhost)進(jìn)行連接才可以通過(guò)認(rèn)證雳旅,此用戶從其他任何主機(jī)對(duì)數(shù)據(jù)庫(kù)進(jìn)行的連接都將被拒絕跟磨。也就是說(shuō),同樣的一個(gè)用戶名岭辣,如果來(lái)自不同的IP地址吱晒,則MySQL將其視為不同的用戶。
MySQL的權(quán)限表在數(shù)據(jù)庫(kù)啟動(dòng)地時(shí)候就載入內(nèi)存沦童,當(dāng)用戶通過(guò)身份認(rèn)證后仑濒,就在內(nèi)存中進(jìn)行相應(yīng)權(quán)限的存取,這樣偷遗,此用戶就可以在數(shù)據(jù)庫(kù)中做權(quán)限范圍內(nèi)的各種操作了墩瞳。
權(quán)限表
系統(tǒng)會(huì)用到名叫“mysql”數(shù)據(jù)庫(kù)(安裝MySQL時(shí)被創(chuàng)建)中user表作為權(quán)限表
我們看看user表的結(jié)構(gòu)(注:本文示例使用的是MySQL5.7.25版本)
mysql> desc user;
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | NULL | |
| x509_issuer | blob | NO | | NULL | |
| x509_subject | blob | NO | | NULL | |
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
| plugin | char(64) | NO | | mysql_native_password | |
| authentication_string | text | YES | | NULL | |
| password_expired | enum('N','Y') | NO | | N | |
| password_last_changed | timestamp | YES | | NULL | |
| password_lifetime | smallint(5) unsigned | YES | | NULL | |
| account_locked | enum('N','Y') | NO | | N | |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
45 rows in set (0.00 sec)
當(dāng)用戶進(jìn)行連接的時(shí)候,權(quán)限表的存取過(guò)程有以下現(xiàn)個(gè)階段氏豌。
- 先從user表中的
Host
喉酌、User
、authentication_string
(密碼)泵喘、password_expired
和password_lifetime
這幾個(gè)字段中判斷連接的IP泪电、用戶名和密碼是否存在于表中,如果存在纪铺,則通過(guò)身份驗(yàn)證相速,否則拒絕連接。 - 如果驗(yàn)證通過(guò)鲜锚,再通過(guò)以
_priv
結(jié)尾的那些枚舉字段(這些都是用戶的權(quán)限開關(guān)(Y/N))得到用戶擁有的權(quán)限突诬。
賬號(hào)管理
賬號(hào)管理主要包括賬號(hào)的創(chuàng)建、權(quán)限更改和賬號(hào)的刪除芜繁。用戶連接數(shù)據(jù)庫(kù)的第一步都從賬號(hào)創(chuàng)建開始旺隙。
有兩種方法可以用來(lái)創(chuàng)建賬號(hào):使用GRANT
語(yǔ)法創(chuàng)建或者直接操作授權(quán)表,但更推薦使用第一種方法骏令,因?yàn)椴僮骱?jiǎn)單蔬捷,出錯(cuò)幾率更少。
我們用幾個(gè)例子來(lái)說(shuō)明吧:
-
創(chuàng)建用戶
創(chuàng)建用戶tom伏社,權(quán)限為可以在所有數(shù)據(jù)庫(kù)上執(zhí)行所有權(quán)限抠刺,只能從本地進(jìn)行連接塔淤。
mysql> GRANT ALL PRIVILEGES ON *.* TO tom@localhost IDENTIFIED BY 'tompassword' WITH GRANT OPTION;
如果你執(zhí)行這個(gè)語(yǔ)句碰到以下錯(cuò)誤:
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
。這個(gè)是密碼策略的問(wèn)題速妖,請(qǐng)?jiān)O(shè)置比較復(fù)雜的密碼高蜂,或者修改密碼策略,這里就不詳細(xì)說(shuō)了罕容。GRANT命令說(shuō)明:
ALL PRIVILEGES
是表示所有權(quán)限备恤,你也可以使用select、update等權(quán)限锦秒。ON
用來(lái)指定權(quán)限針對(duì)哪些庫(kù)和表露泊,格式是數(shù)據(jù)庫(kù)名.表名
类嗤,這里*.*
表示所有數(shù)據(jù)庫(kù)和所有表巾钉。TO
表示將權(quán)限賦予某個(gè)用戶。tom@localhost
瞪浸,表示tom
用戶生真,@
后面接限制的主機(jī)沉噩,可以是IP
、IP段
柱蟀、域名
以及%
川蒙,%
表示任何地方。注意:這里%有的版本不包括本地长已,以前碰到過(guò)給某個(gè)用戶設(shè)置了%允許任何地方登錄畜眨,但是在本地登錄不了,這個(gè)和版本有關(guān)系术瓮,遇到這個(gè)問(wèn)題再加一個(gè)localhost的用戶就可以了康聂。IDENTIFIED BY
指定用戶的登錄密碼, 這里'tompassword'
就是用戶tom的密碼胞四。WITH GRANT OPTION
這個(gè)選項(xiàng)表示該用戶可以將自己擁有的權(quán)限授權(quán)給別人早抠。注意:經(jīng)常有人在創(chuàng)建操作用戶的時(shí)候不指定WITH GRANT OPTION選項(xiàng)導(dǎo)致后來(lái)該用戶不能使用GRANT命令創(chuàng)建用戶或者給其它用戶授權(quán)。備注:可以使用
GRANT
重復(fù)給用戶添加權(quán)限撬讽,權(quán)限疊加,比如你先給用戶添加一個(gè)select權(quán)限悬垃,然后又給用戶添加一個(gè)insert權(quán)限游昼,那么該用戶就同時(shí)擁有了select和insert權(quán)限。使用
GRANT
操作用戶權(quán)限之后尝蠕,再使用FLUSH PRIVILEGES
命令來(lái)刷新權(quán)限使其立即生效mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
-
查看用戶的權(quán)限
直接使用
SHOW GRANTS
默認(rèn)查看root@localhost
的權(quán)限mysql> SHOW GRANTS; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | | GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+ 2 rows in set (0.01 sec)
查看某個(gè)用戶的權(quán)限
mysql> SHOW GRANTS FOR tom@localhost; +----------------------------------------------------------------------+ | Grants for tom@localhost | +----------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'tom'@'localhost' WITH GRANT OPTION | +----------------------------------------------------------------------+ 1 row in set (0.00 sec)
-
收回權(quán)限
mysql> REVOKE DELETE ON *.* FROM 'tom'@'localhost'; Query OK, 0 rows affected (0.00 sec)
-
對(duì)用戶賬戶重命名
mysql> RENAME USER tom@localhost to jerry@localhost; Query OK, 0 rows affected (0.00 sec)
-
刪除用戶
mysql> DROP USER jerry@localhost; Query OK, 0 rows affected (0.01 sec)
-
修改和重置密碼
- 用
SET PASSWORD
命令修改密碼
mysql> SET PASSWORD FOR root@localhost = PASSWORD('123456'); Query OK, 0 rows affected, 1 warning (0.01 sec)
- 直接修改user表
mysql> UPDATE user SET authentication_string=PASSWORD('123456root') WHERE user='root' and host='localhost'; Query OK, 1 row affected, 1 warning (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 1 mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
- 在未登錄mysql的情況下用mysqladmin命令修改密碼
$ mysqladmin -uroot -p123456root password 123321
- 在丟失root密碼的時(shí)候
關(guān)閉mysql服務(wù)(根據(jù)你自己的操作系統(tǒng)自行關(guān)閉)烘豌,然后跳過(guò)權(quán)限認(rèn)證啟動(dòng)mysql服務(wù)
$ mysqld_safe --skip-grant-tables &
無(wú)密碼登陸
$ mysql -uroot
進(jìn)入之后使用上面直接修改user表的方法修改root用戶的密碼
最后殺掉
mysqld_safe
和mysqld
的進(jìn)程重新啟動(dòng)mysql服務(wù),用新的密碼登陸吧看彼。
- 用