1. 概述
我们在安装Mysql时会自动安装一个名为mysql的数据库。这个数据库下面存储的是权限表。我们可以使用:show databases ;命令来查看所有的数据库列表。
Mysql会根据这些权限表的内容为每个用户赋予相应的权限,所以我们也是通过这些表来实现管理用户和权限的,如下图所示是在mysql数据库中存在的表:
MySQL存取控制包含2个阶段:
阶段1:服务器检查你是否允许连接。
阶段2:假定你能连接,服务器检查你发出的每个请求。看你是否有足够的权限实施它。例如,如果你从数据库中一个表精选(select)行或从数据库抛弃一个表,服务器确定你对表有select权限或对数据库有drop权限。
2. user表
user表的作用相当与mysql工作流程中的”用户管理模块”,它决定着我们对一个连接允许或拒绝,user表用于记录允许连接到服务器的用户帐号信息,里面的对于数据库的权限是全局生效的
如下图所示是user表结构:
2.1 根据user表结构,表的字段可以分为4类
(1) 用户列
Host 主机名 ——>如果想要从别的机器来登入数据库,Host可以设成 %
User 用户名
Password 密码
用户登录时,首先要判断这三个字段是否匹配,匹配则允许登录;
用户创建时,也是设置这三个字段的值;
修改用户密码时,实际也是修改了user表的Password字段的值。
(2) 权限列(以priv结尾的)
Grant_priv 是否有Grant权限
Shutdown_priv 是否有停止mysql服务的权限
Super_priv 是否有超级权限
Execute_priv 是否有执行存储过程和函数的权限
包含普通权限:查询权限、修改权限等 操作数据库的动作;
包含高级管理权限:关闭服务权限、超级权限、加载用户等 管理数据库的动作;
这些字段只有N和Y两个选项,为安全起见默认值都设为N;
对这些权限的管理可以使用GRANT语句、也可以通过UPDATE user表的这些列来实现。
(3) 安全列
(4) 资源控制列
max_questions 每小时允许执行多少次查询
max_updates 每小时允许执行多少次更新
max_connections 每小时允许建立多少连接
max_user_connections 单个用户可以同时具有的连接数
这些字段默认值为0,表示没有限制
2.2 帐户管理
MYSQL提供许多语句用来管理用户帐号,这些语句可以用来包括登录和退出MYSQL服务器、创建用户、删除用户、密码管理、权限管理
MYSQL数据库的安全性,需要通过帐户管理来保证登录和退出MYSQL
mysql命令的常用参数
-h:主机名或ip,默认是localhost,最好指定-h参数
-u:用户名
-p:密码,注意:该参数后面的字符串和-p不能有空格
-P:端口号,默认为3306
数据库名:可以在命令最后指定数据库名
-e:执行SQL语句,如果指定该参数,将在登录后执行-e后面的命令或sql语句并退出
2.2.1 创建用户
创建用户语法:
CREATE USER user [IDENTIFIED BY [PASSWORD] 'password']
[, user [IDENTIFIED BY [PASSWORD] 'password']]
简单示例:
CREATE USER 'test'@'localhost' IDENTIFIED BY '123';
用户名部分为“test”,主机名默认为“%”(即对所有主机开放权限),如果指定用户登录不需要密码,则可以省略identified BY部分,对于使用插件认证连接的用户,服务器调用指定名称的插件,客户端需要提供验证方法所需要的凭据。,如果创建用户时或者连接服务器时,服务器找不到对应的插件,将返回一个错误.
identified with语法:
CREATE user 'test1'@'localhost'
identified with my_auth_plugin;
identified with只能在MYSQL5.5.7及以上版本使用。identified with和identified by是互斥的,所以对一个帐户来说只能使用一个验证方法。
CREATE USER语句的操作会被记录到服务器日志文件或者操作历史文件中
2.2.2 使用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语句创建一个新用户test1,密码为testpwd,并授予用户对所有数据表的SELECT和UPDATE权限
GRANT SELECT ,UPDATE
ON *.* TO 'test1'@'localhost'
identified BY 'testpwd';
2.2.3 直接操作MYSQL用户表
不管是CREATE USER还是GRANT USER,在创建用户时,实际上都是在user表中添加一条新记录。使用INSERT语句向mysql.user表INSERT一条记录来创建一个新用户,插入的时候必须要有INSERT权限
2.2.4 删除普通用户
使用DROP USER语句删除用户,也可以直接通过DELETE从mysql.user表中删除对应的记录来删除用户,DROP USER语句用于删除一个或多个MYSQL帐户。要使用DROP USER,必须拥有MYSQL数据库的全局CREATE USER 权限或DELETE权限。
2.2.5 root用户修改自己的密码
修改root密码的方式有多种
(1)使用mysqladmin命令在命令行指定新密码:
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用户的密码
SET PASSWORD语句可以用来重新设置其他用户的登录密码或者自己使用的帐户密码
语法
SET PASSWORD=PASSWORD("ROOTPWD")
2.2.6 root用户密码丢失的解决办法
使用–skip-grant-tables选项启动MYSQL服务
使用–skip-grant-tables选项启动MYSQL时,服务器将不加载权限判断,任何用户都能访问数据库
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用户登录了
3. db表
(1)用户被允许连接了,但是是不是可以就能操作所有数据库了呢?
(2)所以我们需要db表/host表,用来规定某一个用户对一个数据库的权限
(3)db表的字段分为两类:
(1)用户列
Host 主机名
Db 数据库名
User 用户名
(2)权限列
用户是先根据user表的内容获得权限,再根据db表的内容获取权限
例如,user表中某用户的Select_priv字段为‘N’,表示所有数据库中的表它都无权查询
但db表中这一用户对student表的Select_priv字段设为了‘Y’,表示它只有查询student表的权限
4. tables_priv表和columns_priv表
(1)同理,即便用户有权对某一数据库操作,那么是不是对所有表都可以操作?对表中的所有记录都可以操作?
(2) tables_priv表用来对单个表进行权限设置
(3)columns_priv表用来对单条记录(列)进行权限设置
(4)其包含的字段主要有:
Host 主机名
Db 数据库名
User 用户名
Table_name 表名
column_name 表示可以对哪些数据列进行操作
Table_priv 对表进行操作的权限(select,insert,update,delete,create,drop,grant,references,index,alter)
Column_priv 对记录进行操作的权限(select,insert,update,references)
Timestamp 修改权限的时间
Grantor 权限的设置者
5. procs_priv表
(1)对存储过程和存储函数进行权限设置
(2)主要字段:
Host 主机名
Db 数据库名
User 用户名
Routine_name 存储过程/存储函数的名字
Routine_type 标识它是FUNCTION(存储函数)还是PROCEDURE(存储过程)
Proc_priv 拥有的权限(Execute、Alter Routine、Grant)
Timestamp 更新的时间
Grantor 权限是谁设置的
6. 用户的权限分配规则
(1)Mysql的权限分配是按照user表—>db表—>tables_priv表—>columns_priv表的顺序进行分配的
(2)如果user表中某一权限的值为Y,就不需要检查往后的表了
(3)如果user表中某一权限的值为N,则依次往后检查每一张表
7. 权限管理操作
7.1 授权
语法:
Methods-1
> grant [权限list] ——> 参考上表
on [datebase-name.table-name]
to ['username'@'hostname']
identified by ['password'] ——> 如果是新创建的用户可以设置密码
with [options]; ——> with关键字之后有5个可选项
options:
grant option:表示被授权的用户可以将这些权限赋予给别的用户
max_queries_per_hour [count]:设置每小时可以允许执行count次查询
max_updates_per_hour [count]:设置每小时可以允许执行count次更新
max_connections_per_hour [count]:设置每小时可以建立count连接
max_user_connections [count]:设置单个用户可以同时具有的count个连接数
Methods-2 授予一个用户全部权限
> grant all privileges on [database-name.table-name] to 'username'@'hostname' with grant option;
7. 2. 查看权限
Methods-1
> show grants for 'hostname'@'hostname' \G
Methods-2
> select * from mysql.user where User='username' and Host='hostname' \G
7.3. 取消权限
> revoke [权限list]
on [datebase-name.table.name]
from ['username'@'hostname'];
取消全部权限:
> revoke all privileges,grant option
from 'username'@'hostname';
7.4. 刷新(加载)权限
flush privileges;