在mysql数据库中,有mysql_install_db脚本初始化权限表,存储权限的表有:
1、user表
2、db表
3、host表
4、table_priv表
5、columns_priv表
6、proc_priv表
MySQL存取控制包括2个阶段:
- 阶段1:server检查你是否同意连接。
- 阶段2:假定你能连接,server检查你发出的每一个请求。看你是否有足够的权限实施它。比如。假设你从数据库中一个表精选(select)行或从数据库抛弃一个表,server确定你对表有select权限或对数据库有drop权限。
server在存取控制的两个阶段使用在mysql
的数据库中的user
、db
和host
表,在这些授权表中字段例如以下:
表名称 | user | db | host |
范围字段 | Host | Host | Host |
User | Db | Db | |
Password | User | ||
权限字段 | Select_priv | Select_priv | Select_priv |
Insert_priv | Insert_priv | Insert_priv | |
Update_priv | Update_priv | Update_priv | |
Delete_priv | Delete_priv | Delete_priv | |
Index_priv | Index_priv | Index_priv | |
Alter_priv | Alter_priv | Alter_priv | |
Create_priv | Create_priv | Create_priv | |
Drop_priv | Drop_priv | Drop_priv | |
Grant_priv | Grant_priv | Grant_priv | |
Reload_priv | |||
Shutdown_priv | |||
Process_priv | |||
File_priv |
对存取控制的第二阶段(请求证实)。假设请求涉及表,server能够另外參考tables_priv
和columns_priv
表。
这些表的字段例如以下:
表名称 | tables_priv | columns_priv |
范围字段 | Host | Host |
Db | Db | |
User | User | |
Table_name | Table_name | |
Column_name | ||
权限字段 | Table_priv | Column_priv |
Column_priv | ||
其它字段 | Timestamp | Timestamp |
Grantor |
每一个授权表包括范围字段和权限字段。
user表主要分为:用户列、权限列、安全列、资源控制列
host表主要分为:用户列、权限列
这里美中不足的是mysql.user 没有一个列是保存用户创建时间的
有时候排查用户问题的时候,比方某个客户在某个时间说连接不上数据库,我们在user表里仅仅能查到是否存在那个用户
可是不知道这个用户的创建时间,也就是说客户说的那个时间到底用户是否已经创建我们是不知道的
帐户管理
MYSQL提供很多语句用来管理用户帐号,这些语句能够用来包含登录和退出MYSQLserver、创建用户、删除用户、password管理、权限管理
MYSQL数据库的安全性,须要通过帐户管理来保证
登录和退出MYSQL
mysql命令的经常使用參数
-h:主机名或ip。默认是localhost。最好指定-h參数
-u:username
-p:password,注意:该參数后面的字符串和-p不能有空格
-P:port号,默觉得3306
数据库名:能够在命令最后指定数据库名
-e:运行SQL语句,假设指定该參数。将在登录后运行-e后面的命令或sql语句并退出
命令运行完之后返回book表的结构,查询返回之后会自己主动退出MYSQL
用户
CREATE USER user [IDENTIFIED BY [PASSWORD] 'password'] [, user [IDENTIFIED BY [PASSWORD] 'password']]
新建普通用户
CREATE USER 'jeffrey'@'localhost' identified BY 'mypass';
username部分为“jeffrey”,主机名默觉得“%”(即对全部主机开放权限)
假设指定用户登录不须要password,则能够省略identified BY部分
对于使用插件认证连接的用户,server调用指定名称的插件。client须要提供验证方法所须要的凭据。
假设创建用户时或者连接server时。server找不到相应的插件,将返回一个错误
identified with语法
CREATE user 'jeffrey'@'localhost' identified with my_auth_plugin;
identified with仅仅能在MYSQL5.5.7及以上版本号使用。
identified with和identified by是相互排斥的。所以对一个帐户来说仅仅能使用一个验证方法。
CREATE USER语句的操作会被记录到server日志文件或者操作历史文件里
比如 ~/.mysql_history。这意味着对这些文件有读取权限的人,都能够读取到新加入用户的明文password
一个办法就是新建用户的时候使用passwordkeyword
CREATE user 'tom'@'localhost' identified BY password'*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';SELECT password('mypass');SELECT * FROM `mysql`.`user` WHERE `User` ='tom';
先查出你的password的哈希值。然后在新建用户的时候输入哈希值
那么在日志里面就仅仅能看到哈希值
使用GRANT语句创建新用户
GRANT USER语句能够用来创建帐户。通过该语句能够在user表中加入一条新记录
比起CREATE USER语句创建的新用户。还须要使用GRANT语句赋予用户权限
使用GRANT语句创建新用户时必须有GRANT权限。
语法
GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] {tbl_name | * | *.* | db_name.*} TO user [IDENTIFIED BY [PASSWORD] 'password'] [, user [IDENTIFIED BY [PASSWORD] 'password']] ... [REQUIRE NONE | [{SSL| X509}] [CIPHER 'cipher' [AND]] [ISSUER 'issuer' [AND]] [SUBJECT 'subject']] [WITH with_option [with_option] ...]
使用GRANT语句创建一个新用户testUser。password为testpwd,并授予用户对全部数据表的SELECT和UPDATE权限
GRANT SELECT ,UPDATE ON *.* TO 'testUser'@'localhost' identified BY 'testpwd'SELECT `Host` ,`User` ,`Select_priv` ,`Update_priv` FROM mysql.user WHERE `User` ='testUser';
运行结果显示运行成功。使用SELECT语句查询用户testUser的权限
查询结果显示SELECT和UPDATE权限字段均为Y
注意:User表中的user和host字段区分大写和小写,在查询的时候要指定正确的username或主机名
直接操作MYSQL用户表
无论是CREATE USER还是GRANT USER。在创建用户时,实际上都是在user表中加入一条新记录。
使用INSERT语句向mysql.user表INSERT一条记录来创建一个新用户
插入的时候必需要有INSERT权限
INSERT INTO mysql.user(host,user,password,[privilegelist])VALUES ('host','username',password('password'),privilegevaluelist)
使用INSERT创建一个新用户。其username称为customer1。主机名为localhost。password为customer1
INSERT INTO mysql.user(host,user,password)VALUES ('localhost','customer1',password('customer1'))
语句运行失败。查看警告信息例如以下:
show WARNINGS ;
由于ssl_cipher这个字段在user表中未定义默认值,所以在这里提示错误信息。
影响insert语句的运行,使用SELECT语句查看user表中的记录
能够看到,插入失败
删除普通用户
使用DROP USER语句删除用户。也能够直接通过DELETE从mysql.user表中删除相应的记录来删除用户
DROP USER语句用于删除一个或多个MYSQL帐户。要使用DROP USER。必须拥有MYSQL数据库的全局
CREATE USER 权限或DELETE权限。
删除testUser这个用户
DROP user 'testUser'@'localhost';
能够发现testUser这个用户已经删除了
使用delete语句删除用户
DELETE FROM mysql.user WHERE `Host`='localhost' and `User`='testUser'
root用户改动自己的password
改动rootpassword的方式有多种
1、使用mysqladmin命令在命令行指定新password
mysqladmin -u root -p password"rootpwd"
2、改动mysql数据库的user表
UPDATE mysql.user SET `Password` =password('rootpwd') WHERE `User`='root' and `Host`='localhost'
password('')函数用来加密用户密码。
运行update之后须要运行flush privileges语句又一次载入用户权限
3、使用SET语句改动root用户的password
SET PASSWORD语句能够用来又一次设置其它用户的登录password或者自己使用的帐户password
语法
SET PASSWORD=PASSWORD("ROOTPWD")
新password必须用PASSWORD函数加密
使用root用户登录到mysql之后运行以下语句
SET password=password('123456')
运行之后须要使用运行flush privileges语句或者重新启动MYSQL又一次载入用户权限
root用户改动普通用户password
1、使用SET语句改动普通用户的password
SET PASSWORD FOR 'USER'@'HOST' =PASSWORD("ROOTPWD")
2、使用update语句改动普通用户的password
UPDATE mysql.user SET `Password` =password('rootpwd') WHERE `User`='root' and `Host`='localhost'
运行完成之后须要使用flush privileges语句或者重新启动MYSQL又一次载入用户权限
3、使用GRANT语句改动普通用户password
GRANT USAGE ON *.* TO 'someuser'@'%' IDENTIFIED BY 'somepwd'
使用以下语句把testUser用户的password改为123456
grant USAGE ON *testUser*TO 'localhost' identified BY '123456';
注意:使用GRANT语句和MYSQLADMIN设置password。他们均会加密password,这样的情况下,不须要使用PASSWORD()函数
普通用户改动password
使用SET语句改动自己的password
SET password=password('newpassword');
比方改动testUser这个用户的password。须要使用testUser这个用户登录到mysql。然后运行
SET password=password('123456');
root用户password丢失的解决的方法
使用--skip-grant-tables选项启动MYSQL服务
使用--skip-grant-tables选项启动MYSQL时,server将不载入权限推断,不论什么用户都能訪问数据库
LINUX下
使用mysqld_safe来启动MYSQL服务,也能够使用/etc/init.d/mysql命令来启动mysql
mysqld_safe --skip-grant-tables user=mysql
或者
/etc/init.d/mysql start-mysqld --skip-grant-tables
启动MYSQL服务后,就能够使用root用户登录了
Windows下
具体能够看一下这篇文章
权限管理
MYSQL中的各种权限
对于GRANT和REVOKE语句,priv_type能够被指定为下面不论什么一种:
权限 | 意义 |
ALL [PRIVILEGES] | 设置除GRANT OPTION之外的全部简单权限 |
ALTER | 同意使用ALTER TABLE |
ALTER ROUTINE | 更改或取消已存储的子程序 |
CREATE | 同意使用CREATE TABLE |
CREATE ROUTINE | 创建已存储的子程序 |
CREATE TEMPORARY TABLES | 同意使用CREATE TEMPORARY TABLE |
CREATE USER | 同意使用CREATE USER, DROP USER, RENAME USER和REVOKE ALL PRIVILEGES。 |
CREATE VIEW | 同意使用CREATE VIEW |
DELETE | 同意使用DELETE |
DROP | 同意使用DROP TABLE |
EXECUTE | 同意用户执行已存储的子程序 |
FILE | 同意使用SELECT...INTO OUTFILE和LOAD DATA INFILE |
INDEX | 同意使用CREATE INDEX和DROP INDEX |
INSERT | 同意使用INSERT |
LOCK TABLES | 同意对您拥有SELECT权限的表使用LOCK TABLES |
PROCESS | 同意使用SHOW FULL PROCESSLIST |
REFERENCES | 未被实施 |
RELOAD | 同意使用FLUSH |
REPLICATION CLIENT | 同意用户询问从属server或主server的地址 |
REPLICATION SLAVE | 用于复制型从属server(从主server中读取二进制日志事件) |
SELECT | 同意使用SELECT |
SHOW DATABASES | SHOW DATABASES显示全部数据库 |
SHOW VIEW | 同意使用SHOW CREATE VIEW |
SHUTDOWN | 同意使用mysqladmin shutdown |
SUPER | 同意使用CHANGE MASTER, KILL, PURGE MASTER LOGS和SET GLOBAL语句,mysqladmin debug命令;同意您连接(一次),即使已达到max_connections。 |
UPDATE | 同意使用UPDATE |
USAGE | “无权限”的同义词 |
GRANT OPTION | 同意授予权限 |
当从旧版本号的MySQL升级时,要使用EXECUTE, CREATE VIEW, SHOW VIEW, CREATE USER, CREATE ROUTINE和ALTER ROUTINE权限
授权
授权就是为某个用户授予权限
授予的权限能够分为多个层级:
· 全局层级
全局权限适用于一个给定server中的全部数据库。这些权限存储在mysql.user表中。GRANT ALL ON *.*和REVOKE ALL ON *.*仅仅授予和撤销全局权限。
· 数据库层级
数据库权限适用于一个给定数据库中的全部目标。
这些权限存储在mysql.db和mysql.host表中。GRANT ALL ONdb_name.*和REVOKE ALL ON db_name.*仅仅授予和撤销数据库权限。
· 表层级
表权限适用于一个给定表中的全部列。
这些权限存储在mysql.talbes_priv表中。GRANT ALL ON db_name.tbl_name和REVOKE ALL ON db_name.tbl_name仅仅授予和撤销表权限。
· 列层级
列权限适用于一个给定表中的单一列。这些权限存储在mysql.columns_priv表中。
当使用REVOKE时,您必须指定与被授权列同样的列。
· 子程序层级
CREATE ROUTINE, ALTER ROUTINE, EXECUTE和GRANT权限适用于已存储的子程序。这些权限能够被授予为全局层级和数据库层级。并且。除了CREATE ROUTINE外,这些权限能够被授予为子程序层级,并存储在mysql.procs_priv表中。
当兴许目标是一个表、一个已存储的函数或一个已存储的过程时,object_type子句应被指定为TABLE、FUNCTION或PROCEDURE。当从旧版本号的MySQL升级时,要使用本子句。您必须升级您的授权表
使用GRANT语句创建一个新用户grantUser,password为“grantpwd”
用户对全部的数据有查询、插入权限,并授予GRANT权限
GRANT SELECT ,INSERT ON *.*TO 'grantUser'@'localhost' identified BY '123456' WITH GRANT OPTION ;
查询显示grantUser被创建成功,并赋予了SELECT、INSERT、GRANT权限。其对应字段值为Y
被授予GRANT权限的用户能够登录MYSQL并创建其它用户帐户,在这里是grantUser的用户
收回权限
收回权限就是取消已经赋予用户的某些权限。收回用户不必要的权限能够在一定程度上保证系统的安全性。
使用REVOKE收回权限之后,用户帐户的记录将从db、host、tables_priv、columns_priv表中删除,可是用户帐号记录依旧
在user表中保存。
语法
REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] {tbl_name | * | *.* | db_name.*} FROM user [, user] ...REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...
使用REVOKE语句,必须拥有mysql数据库的全局CREATE权限或UPDATE权限
使用REVOKE语句取消用户grantUser的INSERT权限
REVOKE INSERT ON *.* FROM 'grantUser'@'localhost';
能够看到grantUser用户的INSERT权限已经被收回了
注意:当从旧版本号的MYSQL升级时,假设要使用EXECUTE、CREATE VIEW、SHOW VIEW、CREATE USER、CREATE ROUTINE、ALTER ROUTINE
权限,必须先升级授权表
查看权限
SHOW GRANT语句能够显示用户的权限信息
语法
show grants FOR 'user'@'host';
使用SHOW GRANT语句查询用户grantUser的权限信息
show grants FOR 'grantUser'@'localhost';
返回结果显示了user表中的帐户信息;接下来以为GRANT SELECT ONkeyword开头,表示用户被授予了SELECT权限。
*.*表示SELECT权限作用于全部数据库的全部数据表;
IDENTIFIED BY 后面的为用户加密后的password
在这里,仅仅是定义了个别的用户权限。GRANT能够显示更加具体的权限信息,包含全局级的和非全局级的权限
假设表层级或者列层级的权限被授予用户的话。他们也能在结果中显示出来。
查看MYSQL里面匿名用户
假设有匿名用户。那么client就能够不用password登录MYSQL数据库,这样就会存在安全隐患
检查匿名用户的方法
SELECT * FROM mysql.user WHERE `User`='';
假设查找到user字段值为空的那条记录。说明存在匿名用户,须要把这条记录删除
假设用匿名用户登录MYSQL就能够看到username是空的
删除语句
DELETE FROM mysql.user WHERE `User`='';SELECT * FROM mysql.user WHERE `User`='';
总结
本文简单的阐述了MYSQL的用户管理和权限方面的内容。希望对大家有帮助
假设大家想更深入学习MYSQL訪问控制方面的知识
能够參考这篇文章:
核心就是两个图
1、client连接请求认证阶段
2、client操作请求认证阶段