目录
一、用户管理
1.创建用户
CREATE USER '用户名'@'主机' [IDENTIFIED BY '密码'][,用户名 [IDENTIFIED BY '密码']];
- 用户名参数表示新建用户的账户,由用户(User) 和主机名(Host) 构成,默认host为'%',表示所有主机(ip)都可登录,也可以使用如'lxc'@'192.168.%.%'的形式
- 可以不指定用户密码,无需密码登录;
2.查看用户
USE mysql; #使用'mysql'数据库
SELECT host,user #查找host和user两个字段
FROM user;
3.修改用户
#直接修改mysql.user表中的字段
UPDATE user
SET user='zhangsan1',host='%'
WHERE user='zhangsan';
#刷新修改
FLUSH PRIVILEGES;
4.删除用户
1.使用DROP USER语句来删除用户时,必须用于DROP USER权限。DROP USER语句的基本语法形式如下:
DROP USER '用户名'@'主机'[,'用户名'@'主机'];
如果不指定host,默认删除的是host为%的用户。否则需要指定host。
2.使用DELETE方式删除
DELETE FROM mysql.user WHERE Host='hostname' AND User='username';
执行完DELETE命令后要使用FLUSH命令来使用户生效。
不推荐通过DELETE直接删除user表的信息,系统会有残留信息保留。而DROP命令会删除用户以及对应的权限,执行命令后你会发现mysql.user表和mysql.db表的相应记录都消失了。
5.设置当前用户密码
1. 使用ALTER USER命令来修改当前用户密码,用户可以使用ALTER命令来修改自身密码,如下语句代表修改当前登录用户的密码。基本语法如下:
ALTER USER USER() IDENTIFIED BY 'new_password';
#USER()函数返回当前用户和主机
2. 使用SET语句来修改当前用户密码 使用root用户登录MySQL后,可以使用SET语句来修改密码,具体 SQL语句如下:
SET PASSWORD='new_password';
该语句会自动将密码加密后再赋给当前用户。
6.修改其他用户密码
1. 使用ALTER语句来修改普通用户的密码 可以使用ALTER USER语句来修改普通用户的密码。
ALTER USER user [IDENTIFIED BY '新密码'] [,user[IDENTIFIED BY '新密码']]…;
2. 使用SET命令来修改普通用户的密码 使用root用户登录到MySQL服务器后,可以使用SET语句来修改普通用户的密码。
SET PASSWORD FOR 'username'@'hostname'='new_password';
3. 使用UPDATE语句修改普通用户的密码(不推荐)
UPDATE mysql.user SET authentication_string=PASSWORD("123456")
WHERE User = "username" AND Host = "hostname";
7.用户密码管理
设置用户密码过期时间
--设置用户的密码过期
ALTER USER user PASSWORD EXPIRE [INTERVAL n DAY|NEVER|DEFAULT];
--1.立即过期、2.指定n天过期、3.从不过期、4.默认时间
设置全局密码过期时间:
--第一种: 建立全局策略,设置密码每隔180天过期
SET PERSIST default_password_lifetime = 180;
#第二种:设置配置文件
[mysqld]
default_password_lifetime=180 #建立全局策略,设置密码每隔180天过期
二、权限管理
1.授予权限的原则
权限控制主要是出于安全因素,因此需要遵循以下几个经验原则 :
- 只授予能满足需要的最小权限 ,防止用户干坏事。比如用户只是需要查询,那就只给select权限就可以了,不要给用户赋予update、insert或者delete权限。
- 创建用户的时候限制用户的登录主机host ,一般是限制成指定IP或者内网IP段。
- 为每个用户设置满足密码复杂度的密码 。
- 定期清理不需要的用户,回收权限或者删除用户。
2.权限列表
#查看权限列表
show privileges;
- CREATE和DROP权限 ,可以创建新的数据库和表,或删除(移掉)已有的数据库和表。。
- SELECT、INSERT、UPDATE和DELETE权限允许在一个数据库现有的表上实施操作。
- INDEX权限允许创建或删除索引,INDEX适用于所有的表。如果具有某个表的CREATE权限,就可以在CREATE TABLE语句中包括索引定义。
- ALTER权限可以使用ALTER TABLE来更改表的结构和重新命名表。
- CREATE ROUTINE权限用来创建保存的程序(函数和程序),ALTER ROUTINE权限用来更改和删除保存的程序, EXECUTE权限 用来执行保存的 程序。
- GRANT权限允许授权给其他用户,可用于数据库、表和保存的程序。
3.授予权限
给用户授权的方式有 2 种,分别是通过把 角色赋予用户给用户授权 和 直接给用户授权 。
授权命令:
GRANT 权限1,权限2,…权限n ON 数据库名称.表名称 TO 用户名@用户地址 [IDENTIFIED BY ‘密码口令’];
该权限如果发现没有该用户,则会直接新建一个用户。
如:
给lxc用户用本地命令行方式,授予db1这个库下的所有表的插改的权限。
GRANT select,update on db1.* to 'lxc'@'localhost'
授予通过网络方式登录的zhangsan用户 ,对所有库所有表的全部权限,密码设为123。注意这里唯独不包括grant的权限
GRANT ALL PRIVILEGES ON *.* TO zhangsan@'%' IDENTIFIED BY '123';
4.查看权限
- 查看当前用户权限:
SHOW GRANTS;
# 或
SHOW GRANTS FOR CURRENT_USER;
# 或
SHOW GRANTS FOR CURRENT_USER();
- 查看指定用户权限:
SHOW GRANTS FOR 'user'@'主机地址' ;
5.收回权限
REVOKE语句取消用户的某些权限。使用REVOKE收回权限之后,用户账户的记录将从 db、host、tables_priv和columns_priv表中删除,但是用户账户记录仍然在user表中保存。
使用DROP删除用户会删除这些权限表中的记录。
收回权限须用户重新登录后才能生效
- 收回权限命令
REVOKE 权限1,权限2,…权限n ON 数据库名称.表名称 FROM 用户名@用户地址;
如:
#收回全库全表的所有权限
REVOKE ALL PRIVILEGES ON *.* FROM lxc@'%';
#收回lxc对db1下所有表的更新权限
REVOKE update on db1.* FROM 'lxc'@'%'
三、权限表
1.user表
user表是mysql中最重要的一个权限表, 记录用户账号和权限信息 。如下:
+--------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Host | char(255) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | NULL | |
| x509_issuer | blob | NO | | NULL | |
| x509_subject | blob | NO | | NULL | |
| max_questions | int unsigned | NO | | 0 | |
| max_updates | int unsigned | NO | | 0 | |
| max_connections | int unsigned | NO | | 0 | |
| max_user_connections | int unsigned | NO | | 0 | |
| plugin | char(64) | NO | | caching_sha2_password | |
| authentication_string | text | YES | | NULL | |
| password_expired | enum('N','Y') | NO | | N | |
| password_last_changed | timestamp | YES | | NULL | |
| password_lifetime | smallint unsigned | YES | | NULL | |
| account_locked | enum('N','Y') | NO | | N | |
| Create_role_priv | enum('N','Y') | NO | | N | |
| Drop_role_priv | enum('N','Y') | NO | | N | |
| Password_reuse_history | smallint unsigned | YES | | NULL | |
| Password_reuse_time | smallint unsigned | YES | | NULL | |
| Password_require_current | enum('N','Y') | YES | | NULL | |
| User_attributes | json | YES | | NULL | |
+--------------------------+-----------------------------------+------+-----+-----------------------+-------+
这些字段可以分成4类,分别是范围列(或用户列)、权限列、安全列和资源控制列。
1.范围列(或用户列)
- host:表示连接类型
- % 表示所有远程通过TCP方式的连接
- ip地址 如 (192.168.1.2、127.0.0.1) 通过指定ip地址进行的TCP方式的连接
- 机器名 通过指定网络中的机器名进行的TCP方式的连接
- localhost 本地方式通过命令行方式的连接 ,比如mysql -u xxx -p xxx 方式的连接。
- user:表示用户名,同一用户通过不同方式连接到mysql服务器的权限是不一样的。
- password: 密码,存在authentication_string字段中,SHA2加密方式
2.权限列
- Grant_priv字段:表示是否拥有GRANT权限
- Shutdown_priv字段:表示是否拥有停止MySQL服务的权限
- Super_priv字段:表示是否拥有超级权限
- Execute_priv字段:表示是否拥有EXECUTE权限。拥有EXECUTE权限,可以执行存储过程和函数。
- Select_priv , Insert_priv等:为该用户所拥有的权限。
3. 安全列
安全列只有6个字段,其中两个是ssl相关的(ssl_type、ssl_cipher),用于加密 ;两个是x509 相关的(x509_issuer、x509_subject),用于标识用户 ;另外两个Plugin字段用于验证用户身份的插件, 该字段不能为空。如果该字段为空,服务器就使用内建授权验证机制验证用户身份。
4. 资源控制列
资源控制列的字段用来限制用户使用的资源 ,包含4个字段,分别为:
- max_questions,用户每小时允许执行的查询操作次数;
- max_updates,用户每小时允许执行的更新操作次数;
- max_connections,用户每小时允许执行的连接操作次数;
- max_user_connections,用户允许同时建立的连接次数。
2.db表
mysql> desc db;
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| Host | char(255) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
+-----------------------+---------------+------+-----+---------+-------+
1. 用户列 db表用户列有3个字段,分别是Host、User、Db。这3个字段分别表示主机名、用户名和数据库名。表示从某个主机连接某个用户对某个数据库的操作权限,这3个字段的组合构成了db表的主键。
2. 权限列 Create_routine_priv和Alter_routine_priv这两个字段决定用户是否具有创建和修改存储过程的权限。
3.tables_priv表和columns_priv表
tables_priv表用来对表设置操作权限 ,columns_priv表用来对表的某一列设置权限 。tables_priv表和columns_priv表的结构分别如图:
mysql> desc tables_priv;
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------------------------+
| Host | char(255) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Grantor | varchar(288) | NO | MUL | | |
| Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
| Table_priv | set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') | NO | | | |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------------------------+
- Host 、 Db 、 User 和 Table_name 四个字段分别表示主机名、数据库名、用户名和表名。
- Grantor表示修改该记录的用户。
- Timestamp表示修改该记录的时间。
- Table_priv 表示对象的操作权限。包括Select、Insert、Update、Delete、Create、Drop、Grant、 References、Index和Alter。
- Column_priv字段表示对表中的列的操作权限,包括Select、Insert、Update和References。
mysql> desc columns_priv;
+-------------+----------------------------------------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------------------------------+------+-----+-------------------+-----------------------------------------------+
| Host | char(255) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Column_name | char(64) | NO | PRI | | |
| Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+----------------------------------------------+------+-----+-------------------+-----------------------------------------------+
4.procs_priv表
procs_priv表可以对存储过程和存储函数设置操作权限。
mysql> desc procs_priv;
+--------------+----------------------------------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------------------------------------+------+-----+-------------------+-----------------------------------------------+
| Host | char(255) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Routine_name | char(64) | NO | PRI | | |
| Routine_type | enum('FUNCTION','PROCEDURE') | NO | PRI | NULL | |
| Grantor | varchar(288) | NO | MUL | | |
| Proc_priv | set('Execute','Alter Routine','Grant') | NO | | | |
| Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
+--------------+----------------------------------------+------+-----+-------------------+-----------------------------------------------+
四、角色管理
引入角色的目的是 方便管理拥有相同权限的用户 。恰当的权限设定,可以确保数据的安全性。
1.创建角色
创建角色使用 CREATE ROLE 语句,语法如下:
CREATE ROLE 'role_name'[@'host_name'] [,'role_name'[@'host_name']]...
角色名称的命名规则和用户名类似。如果 host_name省略,默认为% , role_name不可省略 ,不可为空。
角色和用户比较:
- 创建时都会在mysql.user表中创建记录
- 角色没有密码,且是被锁定状态,不能登录
2.给角色赋予权限
创建角色之后,默认这个角色是没有任何权限的,我们需要给角色授权。给角色授权的语法结构是:
GRANT privileges ON table_name TO 'role_name'[@'host_name'];
查看权限privileges:
SHOW PRIVILEGES\G;
用法和前面的用户相同。
3.查看角色的权限
SHOW GRANTS FOR '角色名';
如:
mysql> grant select on db1.emp to role1;
Query OK, 0 rows affected (0.00 sec)
mysql> show grants for 'role1';
+--------------------------------------------+
| Grants for role1@% |
+--------------------------------------------+
| GRANT USAGE ON *.* TO `role1`@`%` |
| GRANT SELECT ON `db1`.`emp` TO `role1`@`%` |
+--------------------------------------------+
USAGE ON *.*表示连接登录数据库的权限,默认就有
4.回收角色的权限
REVOKE privileges ON tablename FROM 'rolename';
5.删除角色
DROP ROLE role [,role2]...
如果你删除了角色,那么用户也就失去了通过这个角色所获得的所有权限 。
6.给用户赋予角色
角色创建并授权后,要赋给用户并处于激活状态才能发挥作用。
GRANT role [,role2,...] TO user [,user2,...];
将角色的赋给对应的用于,查看该用户的权限会显示出来。
但是还需要激活角色,才能使角色生效,如果未激活,将角色赋给某个用户,将显示NONE。如下
mysql> select current_role();
+----------------+
| current_role() |
+----------------+
| NONE |
+----------------+
7.激活角色
方式1:使用set default role 命令激活角色
#单个激活
SET DEFAULT ROLE ALL TO 'zhangsan'@'localhost';
-- 批量激活
SET DEFAULT ROLE ALL TO
'dev1'@'localhost',
'read_user1'@'localhost',
'read_user2'@'localhost',
'rw_user1'@'localhost';
方式2:将activate_all_roles_on_login设置为ON
默认情况:
mysql> show variables like 'activate_all_roles_on_login';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| activate_all_roles_on_login | OFF |
+-----------------------------+-------+
设置为开启状态,就不需要手动激活角色了,对所有角色永久激活 。运行这条语句之后,用户才真正拥有了赋予角色的所有权限。
SET GLOBAL activate_all_roles_on_login=ON;
8.撤销用户角色
REVOKE role FROM user;