第03章_用户与权限管理
1.2用户管理概述
MySQL用户可以分为普通用户
和root用户
,root用户是超级管理员,拥有所有权限,包括创建用户,删除用户和修改用户的密码等管理权限;普通用户只拥有被授予的各种权限。
==MySQL提供了许多语句来管理用户账号,这些语言可以用来管理包括登录和退出MySQL服务器,创建用户,删除用户、密码管理和权限管理等内容。==
==MySQL数据库的安全性需要通过账户管理来保证。==
MySQL默认提供了4个数据库,其中mysql
数据库当中存储了MySQL的用户账户和权限信息,可以查看mysql
数据库下的用户信息
user mysql;
select host,user from user;
1.1 登录MySQL服务器
启动MySQL服务后,可以通过mysql命令来登录MySQL服务器,命令如下:
mysql –h hostname|hostIP –P port –u username –p DatabaseName –e "SQL语句"
-h参数
后面接主机名或者主机IP,hostname为主机,hostIP为主机IP。-P参数
后面接MySQL服务的端口,通过该参数连接到指定的端口。MySQL服务的默认端口是3306,不使用该参数时自动连接到3306端口,port为连接的端口号。-u参数
后面接用户名,username为用户名。-p参数
会提示输入密码。DatabaseName参数
指明登录到哪一个数据库中。如果没有该参数,就会直接登录到MySQL数据库中,然后可以使用USE命令来选择数据库。-e参数
后面可以直接加SQL语句。登录MySQL服务器以后即可执行这个SQL语句,然后退出MySQL服务器。
mysql -uroot -p -hlocalhost -P3306 mysql -e "select host,user from user"
1.2 创建用户
在MySQL数据库中,官方推荐使用CREATE USER
语句创建新用户。MySQL 8版本移除了PASSWORD加密方法,因此不再推荐使用INSERT语句直接操作MySQL中的user表来增加用户。
使用CREATE USER
语句来创建新用户时,必须拥有CREATE USER权限。每添加一个用户,CREATE USER
语句会在MySQL.user
表中添加一条新记录,但是新创建的账户没有任何权限。如果添加的账户已经存在, CREATE USER语句就会返回一个错误。
CREATE USER语句的基本语法形式如下:
CREATE USER 用户名 [IDENTIFIED BY '密码'][,用户名 [IDENTIFIED BY '密码']];
举例:创建用户xha,并设置密码xu.123456,使其能够在任何ip下访问。
# 默认host是 %,即支持任何ip下的当前用户连接
CREATE USER xha IDENTIFIED BY 'xu.123456';
# 默认host是 localhost,即支持当前ip下的用户连接
CREATE USER 'xha'@'localhost' IDENTIFIED BY '123456';
1.3 修改用户
修改用户名:
UPDATE user SET user = 'zyx' WHERE user = 'xha' AND host = '%';
# 刷新权限
FLUSH PRIVILEGES;
1.4 删除用户
在MySQL数据库中,可以使用DROP USER
语句来删除普通用户,也可以直接在mysql.user
表中删除用户。
方式1:**使用DROP方式删除(推荐)**
DROP USER user[,user]…;
其中,user参数是需要删除的用户,由用户的用户名(User) 和主机名(Host) 组成。DROP USER
语句可以同时
删除多个用户,各用户之间用逗号隔开。
举例:
# 默认删除host为%的用户
DROP USER xha ;
DROP USER 'kangshifu'@'localhost';
方式2:使用DELETE方式删除(不推荐,有残留信息)
可以使用DELETE
语句直接将用户的信息从mysql.user
表中删除,但必须拥有对mysql.user表的DELETE权限,
DELETE语句的基本语法形式如下:
DELETE FROM user WHERE Host=’hostname’ AND User=’username’;
Host
字段和User
字段是user表的联合主键,因此两个字段的值才能确定一条记录,执行完DELETE
命令后要使用FLUSH
命令来使用户生效,命令如下:
FLUSH PRIVILEGES;
注意:不推荐通过
DELETE FROM USER u WHERE USER='1i4'
、进行删除, 系统会有残留信息保留。而
drop user命令会删除用户以及对应的权限,执行命令后你会发现mysql.user表和mysql.db表的相应记录都消失
了。
1.5 设置当前用户密码
适用于root
用户修改自己的密码,以及普通用户登录后修改自己的密码。
root用户拥有很高的权限,因此必须保证root用户的密码安全。root用户可以通过多种方式来修改密码,使用ALTER USER
修改用户密码是MySQL官方推荐的方式。
此外,也可以通过SET语句修改密码。由于MySQL 8中已移除了PASSWORD()函数,因此不再使用UPDATE语句直接操作用户表修改密码。
1. 使用ALTER USER命令来修改当前用户密码
ALTER USER USER() IDENTIFIED BY 'new_password';
2. 使用SET语句来修改当前用户密码
SET PASSWORD='new_password';
1.6 修改其它用户密码
==root用户不仅可以修改自己的密码,还可以修改其它普通用户的密码。==
root用户登录MySQL服务器后, 可以通过ALTER
语句和SET
语句来修改普通用户的密码。
由于PASSWORD()函数已移除, 因此使用UPDATE直接操作用户表的方式已不再使用。
1. 使用ALTER语句来修改普通用户的密码
ALTER USER user [IDENTIFIED BY '新密码']
[,user[IDENTIFIED BY '新密码']]…;
例如:
ALTER USER 'zyx'@'%' IDENTIFIED BY 'xu123456';
2. 使用SET命令来修改普通用户的密码
SET PASSWORD FOR 'username'@'hostname'='new_password';
例如:
SET PASSWORD FOR 'zyx'@'%'='xu.123456';
1.7案例演示:创建用户,给用户授予对应的数据库权限
# 添加授权用户(新创建的用户,默认情况下是没有任何权限的)
create user "用户名" @"%" identified by"密码";
# 允许访问指定数据库下的所有表
grant all privileges on vector_server_user.* to '用户名'@'%' with grant option;
grant all privileges on vector_server_score.* to '用户名'@'%' with grant option;
grant all privileges on nacos_config.* to '用户名'@'%' with grant option;
# 刷新权限
flush privileges;
2. 权限管理
2.1权限概述
关于MySQL的权限简单的理解就是MySQL允许你做你权力以内的事情,不可以越界。比如只允许你执行SELECT操作,那么你就不能执行UPDATE操作。识允许你从某台机器上连接MySQL,那么你就不能从除那台机器以外的其他
机器连接MySQL。
2.2 权限列表
查看MySQL的所有权限:
show privileges;
CREATE和DROP权限
,可以创建新的数据库和表,或删除(移掉)已有的数据库和表。如果将MySQL数据库中的DROP权限授予某用户,用户就可以删除MySQL访问权限保存的数据库。SELECT、INSERT、UPDATE和DELETE权限
允许在一个数据库现有的表上实施操作。SELECT权限
只有在它们真正从一个表中检索行时才被用到。INDEX权限
允许创建或删除索引,INDEX适用于已有的表。如果具有某个表的CREATE权限,就可以在CREATE TABLE语句中包括索引定义。ALTER权限
可以使用ALTER TABLE来更改表的结构和重新命名表。CREATE ROUTINE权限
用来创建保存的程序(函数和程序),ALTER ROUTINE权限
用来更改和删除保存的程序,EXECUTE权限
用来执行保存的程序。GRANT权限
允许授权给其他用户,可用于数据库、表和保存的程序。FILE权限
使用户可以使用LOAD DATA INFILE和SELECT … INTO OUTFILE语句读或写服务器上的文件,任何被授予FILE权限的用户都能读或写MySQL服务器上的任何文件(说明用户可以读任何数据库目录下的文件,因为服务器可以访问这些文件)。
权限分布:
权限分布 | |
---|---|
表权限 | ‘SELECT’、’INSERT’、’UPDATE’、’DELETE’、’CREATE’、’DROP’、’GRANT’、’REFERENCES’、’INDEX’ |
列权限 | ‘SELECT’、’INSERT’、’UPDATE’、’REFERENCES’ |
过程权限 | ‘EXECUTE’、’ALTER’、’ROUTINE’、’GRANT’ |
2.3授予权限的原则
权限控制主要是出于安全因素,因此需要遵循以下几个经验原则
:
1、只授予能满足需要的最小权限
,防止用户干坏事。比如用户只是需要查询,那就只给select权限就可以了,不要给用户赋予update、insert或者delete权限。
2、创建用户的时候限制用户的登录主机
,一般是限制成指定IP或者内网IP段。
3、为每个用户设置满足密码复杂度的密码
。
4、定期清理不需要的用户
,回收权限或者删除用户。
2.3授予权限
给用户授权的方式有2种,分别是通过把角赋予用户给用户授权
和直接给用户授权
。
用户是数据库的使用者,我们可以通过给用户授予访问数据库中资源的权限,来控制使用者对数据库的访问,消除安全隐患。该权限如果发现没有该用户,则会直接新建一个用户。
GRANT 权限1,权限2,…权限n ON 数据库名称.表名称 TO 用户名@用户地址 [IDENTIFIED BY ‘密码口令’];
如下:
给zyx
用户用本地命令行方式,授予enterprise
这个库下的所有表的查询的权限。
GRANT SELECT ON enterprise.* TO 'zyx'@'%';
- 授予通过网络方式登录的joe用户 ,对所有库所有表的全部权限,密码设为123。注意这里唯独不包括grant的权限
GRANT ALL PRIVILEGES ON *.* TO joe@'%' IDENTIFIED BY '123';
ALL PRIVILEGES
是表示所有权限,你也可以使用SELECT、UPDATE
等权限。ON
用来指定权限针对哪些库和表。TO
表示将权限赋予某个用户。.
中前面的*
号用来指定数据库名,后面的*
号用来指定表名。这里的*
表示所有的。- ‘xha‘@’localhost’表示xha用户,@后面接限制的主机,可以是IP、IP段、 域名以及%,%表示任何地方。注意:这里%有的版本不包括本地,以前碰到过给某个用户设置了%允许任何地方登录,但是在本地登录不了,这个和版本有关系,遇到这个问题再加一个localhost的用户就可以了 。
IDENTIFIED BY
指定用户的登录密码。
- 如果需要赋予包括
GRANT
的权限,添加参数“WITH GRANT OPTION
”这个选项即可,表示该用户可以将自己拥有的权限授权给别人。经常有人在创建操作用户的时候不指定WITH GRANT OPTION选项导致后来该用户不能使用GRANT命令创建用户或者给其它用户授权。 - 可以使用GRANT重复给用户添加权限,权限叠加,比如你先给用户添加一个SELECT权限,然后又给用户添加一个INSERT权限,那么该用户就同时拥有了SELECT和INSERT权限。
我们在开发应用的时候,经常会遇到一种需求,就是要根据用户的不同,对数据进行横向和纵向的分组。
- 所谓横向的分组,就是指用户可以接触到的数据的范围,比如可以看到哪些表的数据;
- 所谓纵向的分组,就是指用户对接触到的数据能访问到什么程度,比如能看、能改,甚至是删除。
2.4 查看权限
- 查看当前用户权限
SHOW GRANTS;
# 或
SHOW GRANTS FOR CURRENT_USER;
# 或
SHOW GRANTS FOR CURRENT_USER();
- 查看某用户的全局权限
SHOW GRANTS FOR 'user'@'主机地址';
2.5 收回权限
收回权限就是取消已经赋予用户的某些权限。收回用户不必要的权限可以在一定程度上保证系统的安全性。
MySQL中使用REVOKE
语句取消用户的某些权限。使用REVOKE收回权限之后,用户账户的记录将从db、host、
tables_priv和columns_priv表中删除,但是用户账户记录仍然在user表中保存(删除user表中的账户记录使用DROP
USER语句)。
注意:在将用户账户从user表删除之前,应该收回相应用户的所有权限。
- 收回权限命令
REVOKE 权限1,权限2,…权限n ON 数据库名称.表名称 FROM 用户名@用户地址;
- 举例
收回用户zyx
对于enterprise
数据库的全部权限
REVOKE ALL PRIVILEGES ON enterprise.* FROM 'zyx'@'%';
#收回全库全表的所有权限
REVOKE ALL PRIVILEGES ON *.* FROM zyx@'%';
#收回mysql库下的所有表的插删改查权限
REVOKE SELECT,INSERT,UPDATE,DELETE ON mysql.* FROM zyx@localhost;
- 注意:
须用户重新登录后才能生效
总结
有一些程序员喜欢使用Root超级用户来访问数据库,完全把权限控制放在应用层面实现。这样当然也是可以的。但建议大家,尽量使用数据库自己的角色和用户机制来控制访问权限,不要轻易用Root账号。因为Root账号密码放在代码里面不安全,一旦泄露,数据库就会完全失去保护。而且,MySQL 的权限控制功能十分完善,应该尽量利用,可以提高效率,而且安全可靠。
3.权限表
MySQL服务器通过权限表
来**控制用户对数据库的访问,权限表存放在mysq1数据库中。==MySQL数据库系统会根据这些权限表的内容为每个用户赋予相应的权限。这些权限表中最重要的是user表、db表。== 除此之外,还有
table_pfiv表、column. priv表和proc_ priv表等。在MySQL启动时,服务器将这些数据库表中权限信息的内容读入内存。**
- 查看mysql数据库下的所有表
- 查看user表下的所有字段
- 查看db表下的所有字段
具体操作数据库的权限
- 查看
tables_priv
表下的所有字段
具体操作表的权限
- 查看
columns_priv
表下的所有字段
具体操作表中字段的权限
4.访问控制
4.1访问控制概述
正常情况下,并不希望每个用户都可以执行所有的数据库操作。当MySQL允许一 个用户执行各种操作时,它将首先核实该用户向MySQL服务器发送的连接请求,然后确认用户的操作请求是否被允许。这个过程称为MySQL中的访问控制过程
。
MySQL的访问控制分为两个阶段
- 连接核实阶段
- 请求核实阶段
4.2连接核实阶段
当用户试图连接MySQL服务器时,服务器基于用户的身份以及用户是否能提供正确的密码验证身份来确定接受或者拒绝连接。==即客户端用户会在连接请求中提供用户名、主机地址、用户密码==,MySQL服务器接收到用户请求
后,会使用user表中的host,user和authentication_ string这3个字段匹配客户端提供信息。
服务器只有在user表记录的Host和User字段匹配客户端主机名和用户名,并且提供正确的密码时才接受连接。如果连接核实没有通过,服务器就完全拒绝访问;否则,服务器接受连接,然后进入阶段2等待用户请求。
4.3请求核实阶段
==一旦建立了连接,服务器就进入了访问控制的阶段2,也就是请求核实阶段==。对此连接上进来的每个请求,服务
器检查该请求要执行什么操作、是否有足够的权限来执行它,这正是需要授权表中的权限列发挥作用的地方。这
些权限可以来自user、db、table. _priv和column. _priv表。
确认权限时,MySQL首先检查user表,如果指定的权限没有在user表中被授予,那么MySQL就会继续检查db表,db表是下一安全层级,其中的权限限定于数据库层级,在该层级的SELECT权限允许用户查看指定数据库的所有表中的数据;如果在该层级没有找到限定的权限,则MySQL继续检查tables_priv表以及columns_priv表,如果所有权限表都检查完毕,但还是没有找到允许的权限操作,MySQL将返回错误信息,用户请求的操作不能执行,操作失败。请求核实的过程如图所示。
5. 角色管理
5.1角色的理解
角色是在MySQL 8.0中引入的新功能。在MySQL中, 角色是权限的集合,可以为角色添加或移除权限。用户可以披赋予角色,同时也被授予角色包含的权限。对角色进行操作需要较高的权限。并且像用户账户-样,角色可以
用有授予和撤消的权限。
==引入角色的目的是方便管理拥有相同权限的用户。恰当的权限设定,可以确保数据的安全性,这是至关重要的。==
5.2创建角色
在实际应用中,为了安全性,需要给用户授予权限。当用户数量较多时,为了避免单独给每一个用户授予多个权限,可以先将权限集合放入角色中,再赋予用户相应的角色。
创建角色使用CREATE ROLE
,语法如下:
CREATE ROLE 'role_name'[@'host_name'] [,'role_name'[@'host_name']]...
角色名称的命名规则和用户名类似。如果host_name省略,默认为%
,role_name不可省略
,不可为空。
例如:创建一个manager
和boss
的角色
CREATE ROLE 'manager'@'%';
CREATE ROLE 'boss'@'%';
还可以一次性创建多个角色:
CREATE ROLE 'boss'@'%','employee'@'%';
5.3给角色赋予权限
创建角色后,新角色是没有任何权限的,需要给角色授予权限,授予角色权限的语法如下:
GRANT privileges ON table_name TO 'role_name'[@'host_name'];
上述语句中privileges代表权限的名称,多个权限以逗号隔开。可使用SHOW语句查询权限名称
SHOW PRIVILEGES\G
例如:
- 授予
manager
角色对于enterprise
数据库下的所有表的查询,修改和新增的权限。
GRANT select,update,insert ON enterprise.* TO 'manager'@'%';
- 授予
boss
角色对于所有
数据库下的所有表的权限
GRANT ALL PRIVILEGES ON *.* TO 'boss'@'%';
5.4查看角色的权限
给对应的角色添加权限后,我们可以查看对应角色的权限。
查看角色语法:
SHOW GRANTS FOR 'role_name';
例如:查看manager
的权限
SHOW GRANTS FOR 'manager';
==如上所示,只要你创建了一个角色,系统就会自动给你一个“USAGE
”权限,意思是连接登录数据库的权限
。==
5.5回收角色的权限
角色授权后,可以对角色的权限进行维护,对权限进行添加或撤销。添加权限使用GRANT
语句, 与角色授权相
同。撤销角色或角色权限使用REVOKE
语句。
修改了角色的权限,会影响拥有该角色的账户的权限。
语法如下:
REVOKE privileges ON tablename FROM 'rolename';
例如:
回收manager
角色对于enterprise
数据库中所有表的update
权限
查看修改后的角色权限,发现已经没有update
权限
5.6删除角色
当我们需要对业务重新整合的时候,可能就需要对之前创建的角色进行清理,删除些不会再使用的角色。删除
角色的操作很简单,你只要掌握语法结构就行了。
DROP ROLE role [,role2]...
注意,如果你删除了角色,那么用户也就失去了通过这个角色所获得的所有权限
。
例如:删除boss
角色
DROP ROLE 'boss';
5.7给用户赋予角色
角色创建并授权后,要赋给用户并处于激活状态
才能发挥作用。
GRANT role [,role2,...] TO user [,user2,...];
例如:将角色manager
授予用户xha
GRANT 'manager' TO 'xha';
使用赋予了角色的用户去登录,但是这个账号没有任何权限。这是因为, MySQL 中创建了角色之后,默认都是没有被激活,必须要手动激活,激活以后用户才能拥有角色对应的权限。
查询当前已激活的角色
SELECT CURRENT_ROLE();
5.8激活角色
激活角色的方式又两种:
方式1:使用set default role 命令激活角色
SET DEFAULT ROLE ALL TO '用户名'@'%/localhost';
例如:
SET DEFAULT ROLE ALL TO 'xha'@'%';
但是这种方式需要当前用户退出后再次进入才能获取到对应的角色权限。
查看当前已经激活的角色:
方式2:将activate_all_roles_on_login设置为ON
SET GLOBAL activate_all_roles_on_login=ON;
这条 SQL 语句的意思是,对所有角色永久激活
。
5.9 撤销用户的角色
撤销用户角色的语法如下:
REVOKE role FROM user;
例如:撤销xha
的manager
权限
REVOKE 'manager' FROM 'xha';
5.10设置强制角色(mandatory role)
强制角色是给每个创建账户的默认角色,不需要手动设置。强制角色无法被REVOKE 或者DROP。
方式1:服务启动前设置
[mysqld]
mandatory_roles='role1,role2@localhost,r3@%.atguigu.com'
方式2:运行时设置
SET PERSIST mandatory_roles = 'role1,role2@localhost,r3@%.example.com'; #系统重启后仍然有效
SET GLOBAL mandatory_roles = 'role1,role2@localhost,r3@%.example.com'; #系统重启后失效