第三节:MySQL的授权和认证详解(指令+客户端)

一. 简介

1. MySQL权限

 权限系统的作用是授予来自某个主机某个用户可以查询、插入、修改、删除等数据库操作的权限。

(1). 不能明确的指定拒绝某个用户的连接。

(2). 权限控制(授权与回收)的执行语句包括create user, grant, revoke。

(3). 授权后的权限都会存放在MySQL的内部数据库中(数据库名叫mysql),并在数据库启动之后把权限信息复制到内存中

(4). MySQL用户的认证信息不光包括用户名,还要包含连接发起的主

以下两个ypf被认为不是同一个用户:

SHOW GRANTS FOR 'ypf'@'office.example.com’;
SHOW GRANTS FOR 'ypf'@'home.example.com';

2. 权限级别详解

(1). MySQL权限级别:

 A. 全局性的管理权限,作用于整个MySQL实例级别.

 B. 数据库级别的权限,作用于某个指定的数据库上或者所有的数据库上.

 C. 数据库对象级别的权限,作用于指定的数据库对象上(表、视图等)或者 所有的数据库对象上.

(2). 权限存储在mysql库的user, db, tables_priv, columns_priv, and procs_priv这几个系统表中,待MySQL实例启动后就加载到内存中。

(3). 查看root用户的权限

 

对比root用户在几个权限系统表中的数据
• mysql> select * from user where user=‘root’ and host=‘localhost’; ##都是’Y’
• mysql> select * from db where user=‘root’ and host=‘localhost’; ##无记录
• mysql> select * from tables_priv where host=‘localhost’ and user=‘root’; ##无记录
• mysql> select * from columns_priv where user=‘root’ and host=‘localhost’; ##无记录
• mysql> select * from procs_priv where user=‘root’ and host=‘localhost’; ##无记录

查看 'mysql.sys'用户的权限。

对比mysql.sys用户在几个权限系统表中的数据
• mysql> select * from user where user=‘mysql.sys’ and host=‘localhost’; ##都是’N’
• mysql> select * from db where user=‘mysql.sys’ and host=‘localhost’; ##一条记录,在sys数据库上的Trigger_priv字段为’Y’,
• mysql> select * from tables_priv where host=‘localhost’ and user=‘mysql.sys’; ##一条记录,在sys数据库的sys_config表上有select权限
• mysql> select * from columns_priv where user=‘mysql.sys’ and host=‘localhost’; ##无记录
• mysql> select * from procs_priv where user=‘mysql.sys’ and host=‘localhost’; ##无记录

3. 权限详解

All/All Privileges权限代表全局或者全数据库对象级别的所有权限
Alter:权限代表允许修改表结构的权限,但必须要求有create和insert权限配合。如果是rename表名,则要求有alter和drop原表, create和insert新表的权限
Alter routine:权限代表允许修改或者删除存储过程、函数的权限
Create:权限代表允许创建新的数据库和表的权限
Create routine:权限代表允许创建存储过程、函数的权限
Create tablespace:权限代表允许创建、修改、删除表空间和日志组的权限
Create temporary tables:权限代表允许创建临时表的权限
Create user:权限代表允许创建、修改、删除、重命名user的权限
Create view:权限代表允许创建视图的权限 
Delete:权限代表允许删除行数据的权限
Drop:权限代表允许删除数据库、表、视图的权限,包括truncate table命令
Event:权限代表允许查询,创建,修改,删除MySQL事件
Execute:权限代表允许执行存储过程和函数的权限
File:权限代表允许在MySQL可以访问的目录进行读写磁盘文件操作,可使用的命令包括load data infile,selectinto outfile,load file()函数
Grant option:权限代表是否允许此用户授权或者收回给其他用户你给予的权限
Index:权限代表是否允许创建和删除索引
Insert:权限代表是否允许在表里插入数据,同时在执行analyze table,optimizetable,repair table语句的时候也需要insert权限
Lock:权限代表允许对拥有select权限的表进行锁定,以防止其他链接对此表的读或写
Process:权限代表允许查看MySQL中的进程信息,比如执行show processlist,mysqladmin processlist, show engine等命令
Reference:权限是在5.7.6版本之后引入,代表是否允许创建外键
Reload:权限代表允许执行flush命令,指明重新加载权限表到系统内存中,refresh命令代表关闭和重新开启日志文件并刷新所有的表
Replication client:权限代表允许执行show master status,show slave status,showbinary logs命令
Replication slave:权限代表允许slave主机通过此用户连接master以便建立主从复制关系
Select:权限代表允许从表中查看数据,某些不查询表数据的select执行则不需要此权限,如Select 1+1Select PI()+2;而且select权限在执行update/delete语句中含有where条件的情况下也是需要的
Show databases:权限代表通过执行show databases命令查看所有的数据库名
Show view:权限代表通过执行show create view命令查看视图创建的语句
Shutdown:权限代表允许关闭数据库实例,执行语句包括mysql admin shutdown
Super:权限代表允许执行一系列数据库管理命令,包括kill强制关闭某个连接命令, change master to创建复制关系命令,以及create/alter/drop server等命令
Trigger:权限代表允许创建,删除,执行,显示触发器的权限
Update:权限代表允许修改表中的数据的权限
Usage:权限是创建一个用户之后的默认权限,其本身代表连接登录权限

 例子:创建一个用户ypf,密码为123456,并赋予增删改查的权限。

CREATE USER `ypf`@`%` IDENTIFIED BY '123456';
GRANT Create, Delete, Insert, Update ON *.* TO `ypf`@`%`;

4. 系统权限表详解

(1).  说明

 权限存储在mysql库的user,db, tables_priv, columns_priv, and procs_priv这几个系统表中,待MySQL实例启动后就加载到内存中.

 User表:存放用户账户信息以及全局级别(所有数据库)权限,决定了来自哪些主机的哪些用户可以访问数据库实例,如果有全局权限则意味着对所有数据库都有此权限。

 Db表:存放数据库级别的权限,决定了来自哪些主机的哪些用户可以访问此数据库。

 Tables_priv表:存放表级别的权限,决定了来自哪些主机的哪些用户可以访问数据库的这个表。

 Columns_priv表:存放列级别权限,决定了来自哪些主机的哪些用户可以访问数据库表的这个字段。

 Procs_priv表:存放存储过程和函数级别的权限

(2). User表剖析

   User表和下面的DB表结构类似,都是有很多权限列,有这个权限则为Y,没有这个权限则为N。另外User表中有几个特殊的字段:

 A.  Host:可以是主机名或者ipv4/ipv6的地址。Localhost代表本机,127.0.0.1代表ipv4的本机地址,::1代表ipv6的本机地址;Host_name字段允许使用%和_两个匹配字符,比如’%’代表所有主机,’%.mysql.com’代表来自mysql.com这个域名下的所有主机,‘192.168.1.%’代表所有来自192.168.1网段的主机, ‘’@‘localhost’代表匿名登录的用户。

注:这个字段决定了哪些地址可以使用对应的账号可以访问mysql服务器,%代表运行所有,通常运行远程访问测试期间就是把这个值改为 %。

 B. User: 代表用户名

 C.  Plugin、password(5.6及之前版本存放密码)、authentication_string(5.7及以后版本存放密码)三个字段存放用户认证信息

 D.  Password_expired:设置成’Y’则表明允许DBA将此用户的密码设置成过期而且过期后要求用户的使用者重置密码(alter user/set password重置密码)

 E.  Password_last_changed:作为一个时间戳字段代表密码上次修改时间,执行create user/alter user/set password/grant等命令创建用户或修改用户密码时此数值自动更新

 F.  Password_lifetime:代表从password_last_changed时间开始此密码过期的天

 G.   Account_locked:代表此用户被锁住,无法使用

如下图:

 

(3). DB表剖析

  如下图,表示ypf用户具有对数据库【workflow】的 select、insert、delete、create权限。

(4). Tables_priv表剖析

  如下图,表示ypf用户对于数据库【testdb1】中的表【roleinfor】具有delete、create权限; 【userinfor】表具有delete、create权限。

(5). Columns_priv表剖析

  如下图:表示ypf用户对于数据中【workflow】中表【f_children】中的列【F_Id】【F_input】具有insert,Update权限。

(6). Procs_priv表剖析

 Routine_type是枚举类型,代表是存储过程还是函数,

 Timestamp和grantor两个字段暂时没用

 

二. 指令实操

1. 查看用户权限信息

--查看已经授权给用户的信息
show grants for 'ypf'@'%';

--查看用户的其他非授权信息
show create user 'ypf'@'%';

如图:

 

2. 授权用户(设置权限)

 使用的是grant指令,如果授权的用户 xxx@xxx在服务器中不存在,当指令中带着 identified by xxx 的时候,会先创建该用户再授权,如果该用户已经存在,则直接授权,格式如下

--通用格式
-- 权限: all privilege代表所有权限,或者其他权限,比如增删改查:insert、delete、update、select
-- 目标: '.' 代表作用于整个mysql实例,也可以作用于数据级别、或者表级别等
-- 用户名:这里需要和Host一块写,格式为 xxx@xxx,如果没有特殊符号,可以不加单引号,但是如果有特殊服务,必须加单引号,比如: ypf@localhost 'ypf'@'%'
-- indentified by 设置密码
-- with grant option 允许授权和回收
grant
权限 on 目标 to 用户名 (identified by xxx) (with grant option)


grant
all privileges on *.* to 'root'@'192.168.137.202' identified by '123' with grant option;

以下所有指令都是建立在ypf这个用户已经创建好的情况下执行的,如果没有创建,grant指令中必须带上 identified by xxx 才能创建

(1). 将所有权限授予ypf用户,并且允许起授权和回收

grant all privileges on *.* to 'ypf'@'%'  with grant option;

(2). 将增删改查权限赋予ypf用户操控TestDB1数据库

GRANT Delete, Insert, Select, Update ON TestDB1.* TO 'ypf'@'%';

(3). 将增删改查权限赋予ypf用户操控TestDB1数据库的T_SysErrorLog表

GRANT Delete, Insert, Select, Update ON TABLE TestDB1.T_SysErrorLog TO ypf@'%';

(4). 其他可以参考:

  https://www.cnblogs.com/crxis/p/7044582.html

补充:mysql权限的生效规则。

 执行Grant,revoke,set password,rename user命令修改权限之后,MySQL会自动将修改后的权限信息同步加载到系统内存中

 如果执行insert/update/delete操作上述的系统权限表之后,则必须再执行刷新权限命令才能同步到系统内存中,刷新权限命令包括:flush privileges / mysqladmin flush-privileges / mysqladmin reload

 如果是修改tables和columns级别的权限,则客户端的下次操作新权限就会生效

 如果是修改database级别的权限,则新权限在客户端执行use database命令后生效

 如果是修改global级别的权限,则需要重新创建连接新权限才能生效

 --skip-grant-tables可以跳过所有系统权限表而允许所有用户登录,只在特殊情况下暂时使用

3. 创建用户

(1). 执行create user/grant命令(推荐方式)

方案一: 先创建后授权(先执行create user,后执行 grant)

PS:最终在mysql库中的user表里添加了一条新数据

-- 创建用户lmr,密码为123456
 create user 'lmr'@'%' identified by '123456';
-- 给用户lmr赋予整个mysql实例级别的所有权限
-- all privilege代表所有权限  with grant option代表可回收
 GRANT ALL PRIVILEGES ON *.* TO 'lmr'@'%' WITH GRANT OPTION;

方案二:直接创建授权用户(直接执行 grant)

ps:grant命令对应用户名 xxx@xxx,User表中没有,则该指令如果带着indentified by xxx 会在user表里插入一条新数据,这就是为什么可以直接用grant命令创建并授权用户的原因了。

grant all privileges on *.* to 'lmr2'@'%' identified by '123456' with grant option;

(2). 通过insert语句直接操作MySQL系统权限表.

    即通过insert向mysql库中的user表中插入数据,麻烦,不推荐。

4. 允许远程访问

 允许某个已经存在的用户可以远程访问mysql服务器,本质就是修改User表中的Host字段,比如改为 %,代表允许所有地址访问即可。

(1). 可以通过grant指令插入一个同名的新用户

--允许所有ip访问
grant all privileges on *.* to 'lmr'@'%' identified by '123456' with grant option;

flush privileges; 

(2). 执行update语句

--所有ip
update user set host = '%' where user = 'ypf'; 

--也可以直接插入一条新纪录 
--刷新生效
flush privileges; 

5. 修改密码

 本质是修改user表中的authentication字段(或 password字段)。

-- 方案1:通过指令修改root的密码  (通用)
set password for 'ypf'@'%' = password('123456');

--方案2:通过指令修改root的密码 (通用)
ALTER USER 'ypf'@'%' IDENTIFIED BY '123456';

--方案3: grant指令 (通用)
GRANT USAGE ON *.* TO 'ypf'@'%' IDENTIFIED BY '123456';

--方案4:直接修改对应表 (mysql5.7 及以上)
update mysql.user set authentication_string = password('123456') where user='root';

-- 直接修改表(mysql5.6 及以下)
update mysql.user set password= password('123456') where user='root';

6. 回收用户权限 

 主要使用的是revoke指令。

-- 回收ypf用户在整个mysql实例上的Delete权限
REVOKE Delete ON *.* FROM ypf@'%';

-- 回收ypf用户对testdb1库中的t_syserrorlog表的insert权限
REVOKE Insert ON TABLE testdb1.t_syserrorlog FROM ypf@'%';

7. 删除用户

 使用drop user指令。

--删除用户lmr 
drop user lmr@'%';

7. 设置密码过期策略

(1). 全局配置,作用于所有密码,在mysql配置文件中做如下配置。

default_password_lifetime=180  设置180天过期
default_password_lifetime=0  设置密码不过期

(2). 为每个用户设置过期策略,会覆盖上面的全局配置

-- 设置密码过期时间为90天
ALTER USER 'ypf'@'%' PASSWORD EXPIRE INTERVAL 90 DAY;
-- 设置密码永不过期
ALTER USER 'ypf'@'%' PASSWORD EXPIRE NEVER; 
-- 设置密码为默认过期策略
ALTER USER 'ypf'@'%' PASSWORD EXPIRE DEFAULT; 
-- 设置密码马上过期
ALTER USER 'ypf'@'%' PASSWORD EXPIRE;

8. 设置用户资源限制

-- 每小时最大查询数为10,每小时最大更新数为20,每小时最大连接数为30,最大用户连接数为40
ALTER USER lmr2@'%' WITH
MAX_QUERIES_PER_HOUR 10
MAX_UPDATES_PER_HOUR 20
MAX_CONNECTIONS_PER_HOUR 30
MAX_USER_CONNECTIONS 40;

 注意:如果要取消限制,将对应参数的值改为0即可。

9. 锁定用户

 用户锁定后,则不能登录mysql

--默认创建用户名是不带锁的(下面两句指令等价)
create user abc2@localhost identified by '123456';
create user abc2@localhost identified by '123456' account lock;
--创建用户名的时候加锁
create user abc2@localhost identified by '123456' account lock;
--加锁
alter user 'mysql.sys'@localhost account lock;
--解锁
alter user 'mysql.sys'@localhost account unlock;

 

 

三. 客户端实操

  这里主要介绍通过 Navicat Premium 15来操作

1. 新建用户

2. 配置基础信息

 用户名、哪些地址可以访问、密码、密码过期策略。

 

 3. 配置访问次数

  这里一般不做特殊配置,保持默认即可,也就是不限制。

4. 配置服务器权限

 这里配置的权限是针对整个MySQL实例而言的。比如配置 增删改查 权限。

 

 4. 配置详细的权限

 这里指配置 数据库级别、表级别、列级别、存储过程级别等的权限,比如配置 表级别的权限。

PS:通常配置DB级别的权限,配置Alter、Create、Insert、Delete、Update、Select权限。

5. 查看对应的语句,保持即可。 

 PS:修改密码或权限的时候同样打开上述的可视化界面修改即可。

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

 

posted @ 2020-11-12 07:47  Yaopengfei  阅读(1124)  评论(1编辑  收藏  举报