MySQL用户权限管理
知识要点
了解mysql的默认用户
权限的分类
用户的创建
给用户授权
废除用户权限
MySQL的认证方式
用户名 密码 登录地址
root@localhost(登录主机的地址—客户端) 密码
客户端:要通过什么用户通过什么密码登录服务器
用户名 密码 要登录的服务器的ip地址 服务器提供的mysql服务的端口号
服务端:验证客户端的登录信息是否在我的用户表里
认证三项:用户名 密码 客户端的登录主机(host)
mysql.user表(涉及到客户端连接)
补充: mysql> desc mysql.user; ##desc查看mysql.user表中列的属性,包括用户名 登录主机 还有各类的权限表,密码的相关属性 enum是指枚举
type是指类型 null是指是否允许为空 key是指有没有索引 default是指有没有默认值 extra是备注
mysql> select user,host,authentication_string from mysql.user; ##在mysql.user表里查看用户名 登录主机 密码(在高版本中密码不以明文存储)的等信息
了解mysql默认的用户
当全新的MySQL数据库安装完毕后,系统就为我们默认地创建了几个用户:管理员用户root以及匿名用户。通过查看名为mysql的系统数据库中的user表,可以看到所有的用户名及其全局权限(Global Privileges)
mysql> select user,host from mysql.user;
±--------------±----------+
| user | host |
±--------------±----------+
| mysql.session | localhost |
| mysql.sys | localhost | #没有全局权限
| root | localhost | # mysql的超级管理员,拥有全部的全局权限
±--------------±----------+
6 rows in set (0.00 sec)
mysql>
1.mysql> select * from mysql.user\G ##查看mysql.user表中所有列的信息 \G显示比较清晰。通过显示输出可以看到 root @localhost拥有全部的全局权限。mysql.sys没有全局权限
2.mysql> show grants for ‘mysql.sys’@‘localhost’; ##查看mysql.sys的权限表
±--------------------------------------------------------------+
| Grants for mysql.sys@localhost |
±--------------------------------------------------------------+
| GRANT USAGE ON . TO ‘mysql.sys’@‘localhost’ |
| GRANT TRIGGER ON sys
.* TO ‘mysql.sys’@‘localhost’ | #TRIGGER触发器权限
| GRANT SELECT ON sys
.sys_config
TO ‘mysql.sys’@‘localhost’ | # 有sys数据库的sys_config表的SELECT权限
±--------------------------------------------------------------+
3 rows in set (0.01 sec)
3.mysql> show privileges; ##查看总的权限表
Usage | Server Admin | No privileges - allow connect only ##没有权限,只是允许连接
4.‘mysql.sys’@’localhost’:
用于 sys schema中对象的定义。使用 mysql.sys 用户可避免DBA重命名或者删除root用户时发生的问题。该用户已被锁定,客户端无法连接。
5.‘mysql.session’@’localhost’:
插件内部使用来访问服务器。该用户已被锁定,客户端无法连接。
6.‘root’@’localhost’:
其用于管理。该用户拥有所有权限,可执行任何操作
7.权限:不要轻易的授权给用户超级权限,授予给用户的权限只要满足用户的操作即可,不 要赋予多余权限 (select/insert/delete/update)
了解不存在用户的默认行为
1.在低版本中存匿名用户(不存在用户)的概念,使用匿名用户登录时,可以不使用密码,随便一个用户名就能登录,也不会检查登录主机,但是匿名用户的权限非常低,不会对数据库自身造成影响。但危害是在正常存在的用户在登录,有可能会被认为是匿名用户
2.在刚创建低版本mysql时可以使用mysql> select user,host from mysql.user;检查匿名用户是否存在
删除匿名用户(delete from mysql.user where user=’’;)匿名用户的特点是mysql.user表中user的列值=’’;
3.真实存在的用户有生产库/业务库的真实权限
4.可见,匿名用户有权看到两个数据库:一个名为information_schema的系统数据库和一个test数据库。它对test数据库拥有全部权限,可以在里面创建表,进行DML操作(修删改查)等。对information_schema系统数据库中的表拥有查询权限,但是不能执行DML操作
5.低版本数据库存在,高版本已经不允许匿名用户登录数据库,系统中不存在匿名用户
权限分类
语法:grant 权限操作分类 on 数据库作用范围权限分类 to 某个用户;
按照权限的授予级别,可分成以下几类:
show privileges; ##查看数据库中支持的权限有哪些
数据库作用范围权限分类
1.全局权限Global Privileges:测试举例
它是管理权限,作用到服务器上的所有数据库。要授予全局权限,使用 ON *.的语法,.*表示所有数据库的所有表(对象,视图等)中。MySQL 把全局权限保存在 mysql.user 表中
2.数据库权限Database Privileges:测试举例
作用到某个特定数据库的所有对象上。要授予数据库权限,使用 ON db_name.* 的语法,db_name.*表示db_name数据库下的所有表(对象,视图等)。 MySQL 把数据库权限保存在 mysql.db 表中
3.表权限Table Privileges:测试举例
应用到某个特定表的所有列上。要授予表权限,使用 ON db_name.tbl_name 的语法。 MySQL 把表权限保存在 mysql.tables_priv 表中
4.列权限
权限操作分类: 使用逗号分隔
1.列权限
作用在特定表的特定列上,在权限操作分类中体现列权限 select(col_name),记录到mysql.columns_prive表中 field
2.存储过程权限
作用在存储过程和函数上,记录到mysql.procs_prive表中 procedure
3.代理用户权限
作用是使一个用户成为另一个用户的代理,记录到mysql.proxies_priv表中 proxy
具体分类
在grant和revoke语句中可用的权限如下表所示:
补充:
1.ALL权限 谨慎对待 包含着管理数据库的权限
在mysql.user表中,除了Grant_priv是N外,所有的_prive结尾的列值都是Y
grant option:表示我自己有的权限可以授权给别人
2.event-mysql的时间调度-linux下的crontab
3.mysql> show processlist; #查看当前正在运行的进程列表
command是指执行了什么操作 state是指状态 info是指执行语句 id进程号(可以使用kill杀死)
权限检查顺序
Mysql数据库下的表user(全局权限)、db(数据库权限)、tables_priv(表权限)、columns_priv(列权限)、procs_priv(存储过程权限)、proxies_priv(代理用户权限)共同构成授权表
权限检查顺序如下图:
创建用户
create user的使用语句
CREATE USER user_specification [, user_specification] …
[REQUIRE {NONE | ssl_option [[AND] ssl_option] …}]
[WITH resource_option [resource_option] …]
[password_option | lock_option] …
user_specification:
user_name [ auth_option ]
auth_option: {认证选项
IDENTIFIED BY ‘auth_string’
| IDENTIFIED BY PASSWORD ‘hash_string’
| IDENTIFIED WITH auth_plugin
| IDENTIFIED WITH auth_plugin AS ‘hash_string’
| IDENTIFIED WITH auth_plugin BY ‘auth_string’
}
ssl_option: {加密连接选项
SSL | X509 | CIPHER ‘cipher’
| ISSUER 'issuer‘ | SUBJECT ‘subject’
}
resource_option: {使用资源选项 ##说明:是对使用资源的限制
MAX_QUERIES_PER_HOUR count ##最大的资源访问量
| MAX_UPDATES_PER_HOUR count ##每小时最大更新
| MAX_CONNECTIONS_PER_HOUR count ##每小时最大连接
| MAX_USER_CONNECTIONS count ##每小时最大的连接数量
}
password_option: {密码过期选项
PASSWORD EXPIRE --立即过期
| PASSWORD EXPIRE DEFAULT --360天 ##指定过期的天数,360天可以换成任意天数
| PASSWORD EXPIRE NEVER ##永不过期
| PASSWORD EXPIRE INTERVAL N DAY ##间隔多少天后过期
}
lock_option: {账户锁定选项
ACCOUNT LOCK ##账号锁定
| ACCOUNT UNLOCK ##账号解锁
}
注意:上述语法中,在MySQL 5.7.6之前,只有第1行的create user子句
和其它数据库不同,MySQL使用用户名、密码和登录位置来验证用户
补充:使用grant也可以新建用户
grant all on . to ‘u1’@’%’ identified by ‘123’ with grant option; ##新建一个u1@%用户,这个用户有所有权限
如果不加密码也想创建成功的话,需要执行下面的语句
mysql> show variables like ‘sql_mode’;
±--------------±------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
±--------------±------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
±--------------±------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> set @@session.sql_mode=‘ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION’; ##去掉 NO_AUTO_CREATE_USER不自动创建用户
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> grant all on . to ‘u22’@’%’ with grant option; ##创建没有密码的u22成功
Query OK, 0 rows affected, 1 warning (0.00 sec)
示例1:创建一个新用户demo,密码为demo,允许从本机登录
create user ‘demo’@‘localhost’ identified by ‘demo’;
注意:用户名和主机名要分别用引号括起来(如果用户名没有特殊字符,主机名没有特殊字符和通配符%,也可以不加引号)。密码必须用引号括起来
如果不指定主机名,默认的主机名是百分号%,它代表任意主机
例如:
示例2:创建一个新用户demo1,密码为demo1,允许从任意主机登录
create user ‘demo1’ identified by ‘demo1’;
或者
create user ‘demo1’ @’%’ identified by ‘demo1’;
示例3:创建一个新用户demo2,没有密码,允许从任意主机登录
create user ‘demo2’;
注意:如果两个用户具有相同的用户名但是主机名不同,MySQL把他们看做不同的用户
如果创建的用户已经存在,则抛出异常
当create user语句执行成功后,便在授权表mysql.user中写上一行
示例4:查询所有的用户账户
select user,host,authentication_string(认证字符串) from mysql.user;
一个新用户创建出来后,它可以连接到数据库,并有权看到information_schema的系统数据库。对information_schema系统数据库中的表拥有查询权限,但是不能执行DML(增删改查等)操作。如果还想进行其它操作,必须给他授权
mysql的登录方式
1)本地socket方式
msql -uroot -p123 -S /usr/local/mysql/data/mysql.sock
2)网络方式
127.0.0.1(本地回环)—识别成了localhost
IP地址—网络
修改用户名
语法:该语句不影响用户的密码
RENAME USER old_user TO new_user
[, old_user TO new_user] …
示例5:将用户demo1和demo2分别改名为newdemo1和newdemo2
rename user
‘demo1’@‘localhost’ to ’newdemo1’@‘127.0.0.1’,
‘demo3’@’%’ to ‘newdemo2’@‘127.0.0.1’;
注:修改用户名时一定要将主机名写上,否则会创建登录主机是%的用户
修改密码
一共有三种方式,
1.set password for ‘u1’@’%’ =password(‘123’)
2. alter user ‘u1’@’%’ identified by ‘123’ 推荐使用
3. grant all on . to ‘u1’@’%’ identified by ‘123’
注意:从5.7.6 版本开始,grant语句不提倡使用( is deprecated )。使用ALTER USER语句代替:
ALTER USER user_name IDENTIFIED BY 'auth_string‘;
SET PASSWORD语法
SET PASSWORD [FOR user_name] = password_option;
password_option: {
PASSWORD(‘auth_string’)
| ‘auth_string‘ --只适合5.7.6及其之后的版本
| ‘hash_string‘ --只适合5.7.6之前的版本
}
‘auth_string’:未加密的明文字符串密码。PASSWORD函数将其加密后保存。 ‘hash_string’:已经加密的密码
示例6:修改自己的密码
set password=password(‘123’);
如果你具有mysql数据库的update权限,就可以修改别人的密码
示例7:修改demo用户的密码
set password for [email protected] =password(‘123’);
给用户授权
GRANT的适用语法
GRANT priv_type [(column_list)]
[, priv_type [(column_list)]] …
ON [object_type] priv_level
TO user_specification [, user_specification] …
[REQUIRE {NONE | ssl_option [[AND] ssl_option] …}]
[WITH {GRANT OPTION | resource_option} …]
object_type: {
TABLE | FUNCTION | PROCEDURE
}
priv_level: {
* | . | db_name.* | db_name.tbl_name
| tbl_name | db_name.routine_name
}
user_specification:
user_name [ auth_option ]
auth_option: { # As of MySQL 5.7.6
IDENTIFIED BY ‘auth_string’
| IDENTIFIED BY PASSWORD ‘hash_string’
| IDENTIFIED WITH auth_plugin
| IDENTIFIED WITH auth_plugin AS ‘hash_string’
| IDENTIFIED WITH auth_plugin BY ‘auth_string’
}
ssl_option: {
SSL | X509 | CIPHER 'cipher’ | ISSUER ‘issuer’
| SUBJECT ‘subject’
}
resource_option: {
| MAX_QUERIES_PER_HOUR count
| MAX_UPDATES_PER_HOUR count
| MAX_CONNECTIONS_PER_HOUR count
| MAX_USER_CONNECTIONS count
}
授予表权限
注意:如果被授权的用户不存在,那么grant语句会自动创建新的账户,除非设置参数sql_mode包含“NO_AUTO_CREATE_USER” 。
mysql> grant all on test.a to ‘bbb’@‘localhost’;
ERROR 1133 (42000): Can’t find any matching row in the user table
mysql> grant all on test.a to ‘bbb’@‘localhost’ identified by ‘123’; ##新建了bbb用户
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show warnings; ##查看告警信息
±--------±-----±-----------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
±--------±-----±-----------------------------------------------------------------------------------------------------------------------------------+
| Warning | 1287 | Using GRANT for creating new user is deprecated and will be removed in future release. Create new user with CREATE USER statement. |
±--------±-----±-----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
授予列权限
示例9:授予用户bob可以对test.a表的id和name列进行更新
grant update(id,name)
on test.a
to ‘bob’@‘localhost’;
注意:权限都是单独授予的,对某个表具有update权限不会导致自动得到select权限
授予数据库权限
表权限只针对某一张表,可针对整个数据库授权
示例10:授予bob可以对test数据库中的所有表进行查询
grant select
on test.* ## test.表示test数据库中的所有表
to bob;
示例11:授予jim在 test数据库中创建、修改、删除表的权限以及创建视图的权限
grant create,alter,drop,create view
on test.
to jim;
授予全局权限
示例12:授予jim可以对当前数据库中的所有表进行查询
grant select
on *
to jim;
*号表示当前数据库
授予全局权限,应用到所有数据库上
示例13:授予jim可以创建、删除数据库以及对所有数据库中的所有表进行create、alter和drop
grant create,alter,drop
on . ##*.*也可以更换为其他具体的数据库
to jim;
示例14:授予jim可以创建新用户
grant create user
on .
to jim;
示例15:授予newroot1具有和root@localhost一样的权限
grant all
on .
to ‘newroot1’@’localhost’ with grant option; ##with grant option表示也可以授予别人权限
查看自己的权限 查看别人的权限:
show grants; show grants for 用户;
权限的传递
with grant option子句
通过在grant语句的最后使用该子句,就允许被授权的用户把得到的权限继续授给其它用户
示例16:授予jim对ceshi表具有select权限,并允许他把权限授给其它用户
grant select on test.ceshi to jim with grant option;
以jim连接登录,执行:
grant select on test.ceshi to bob;
废除权限
REVOKE
priv_type [(column_list)]
[, priv_type [(column_list)]] …
ON [object_type] priv_level
FROM user [, user] …
—废除用户在所有级别上的权限:
REVOKE ALL PRIVILEGES, GRANT OPTION
FROM user [, user] …
示例17:废除aaa用户对ceshi表的查询权限
REVOKE ALL PRIVILEGES ON test.ceshi from ‘aaa’@‘localhost’;
再以aaa执行查询:
mysql> select * from test.ceshi;
ERROR 1142 (42000): SELECT command denied to user ‘aaa’@‘localhost’ for table ‘ceshi’
mysql>
示例18:废除jim对test.ceshi 表的select权限
revoke select on test.ceshi from jim;
因为jim通过with grant option把该权限又授给了bob,因此bob也失去了对test.ceshi 表的select权限
示例19:要废除jim得到的with grant权限,使用以下语句:
revoke grant option on test.ceshi from jim;
常见问题
主机名使用localhost还是127.0.0.1?
使用localhost,是通过socket来连接;
使用127.0.0.1,是通过tcp/ip来连接 ##使用本地回环
不要把mysql系统数据库的权限授给用户 ##mysql系统数据库里面有很多权限表
不要随便授予super权限 ##super是管理数据库的权限
show privileges;
用户具有usage权限意味着“没有权限”,它只表示该用户可以连接到数据库。无法废除该权限
select * from mysql.tables_prive ##查看所有表的权限
select * from mysql.columns_prive ##查看所有列的权限
select * from mysql.db ##查看mysql数据库的所有表的信息
select connection_id(); ##查看当前回话的编号
select * from sys.session; ##查看编号对应的用户名等信息