Current user: root@localhost
SSL: Not in use
Server version: 8.0.18 MySQL Community Server - GPL
Protocol version: 10
Connection: Localhost via UNIX socket

MYSQL用户管理
1.1 用户的创建、授权在8.0中发生了改变
在5.7版本数据库中:
通过grant语句可以正常创建用户;
root@localhost [(none)]> grant all privileges on *.* to mysql@'localhost' identified by 'mysql1234';
Query OK, 0 rows affected, 2 warnings (0.00 sec)
root@localhost [(none)]>
复制
我们看下warnings是什么:
root@localhost [(none)]> show warnings;
+---------+------+------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 1285 | MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work |
| Warning | 1287 | Using GRANT for creating new user is deprecated and will be removed in future release. Create new user with CREATE USER statement. |
+---------+------+------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
复制
5.7版本中通过warning的方式告知我们以后的版本中grant方式来创建新用户的方式会被废弃掉,建议使用create user的方式。
在8.0 版本数据库中:
root@localhost [(none)]> grant all privileges on *.* to test@'localhost' identified by 'mysql12341234';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by 'mysql12341234'' at line 1
复制
啊哦,直接报错了。看来以前的grant创建用户的方式是被废弃掉了。
在8.0中,创建用户需要分别用两条语句来完成:
root@localhost [(none)]> create user test@'localhost' identified by 'mysql12341234';
Query OK, 0 rows affected (0.00 sec)
root@localhost [(none)]>
root@localhost [(none)]> grant all privileges on *.* to test@'localhost';
Query OK, 0 rows affected, 1 warning (0.01 sec)
复制
回收权限
root@localhost [(none)]> revoke all privileges on *.* from test@'localhost';
Query OK, 0 rows affected (0.00 sec)
复制
再次查看权限:
root@localhost [(none)]> show grants for test@'localhost';
+------------------------------------------+
| Grants for test@localhost |
+------------------------------------------+
| GRANT USAGE ON *.* TO `test`@`localhost` |
+------------------------------------------+
1 row in set (0.00 sec)
复制
之前授予的权限已经被回收掉了;
1.2 用户密码的加密
在MySQL8.0中,默认的身份认证插件也由mysql_native_password改为了caching_sha2_password,且默认的加密方式是sha2.
root@localhost [(none)]> select user,host,plugin from mysql.user;
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | mysql_native_password |
| test | localhost | mysql_native_password |
+------------------+-----------+-----------------------+
5 rows in set (0.00 sec)
复制
root用户和test用户的认证插件是进行过调整,使用的还是之前老的认证插件,mysql.infoschema 和mysql.session、mysql.sys都是系统默认创建的,用户的认证插件都是caching_sha2_password 。
如果将8.0已有的sha2密码修改为sha1的模式,有两种方法可以实现:
方法1: 创建/修改用户的时候指定认证插件
root@localhost [(none)]> ALTER USER 'test'@'localhost' IDENTIFIED WITH mysql_native_password by 'mysql1234';
Query OK, 0 rows affected (0.01 sec)
复制
方法2:调整配置文件my.cnf
[mysql@Tdongkf base8018]$ cat mysql/my3307/my.cnf |grep pass
default_authentication_plugin = mysql_native_password
[mysql@Tdongkf base8018]$
root@localhost [(none)]> show variables like 'default_authentication_plugin%';
+-------------------------------+-----------------------+
| Variable_name | Value |
+-------------------------------+-----------------------+
| default_authentication_plugin | mysql_native_password |
+-------------------------------+-----------------------+
1 row in set (0.00 sec)
复制
这样,创建用户的时候默认就是使用mysql_native_password认证插件了。
但是,建议在8.0中使用caching_sha2_password 认证协议,caching_sha2_password 实现SHA-256密码散列,但使用缓存来解决连接时的延迟问题。 它还支持更多连接协议,并且不需要针对基于RSA密钥对的密码交换功能进行OpenSSL连接。并且提供比mysql_native_password更安全的密码加密和更好的性能。
1.3 用户密码的过期时间
在mysql5.7或8.0版本中,是禁用自动密码过期的。
可以通过如下命令来查看:
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| default_password_lifetime | 0 |
+---------------------------+-------+
1 row in set (0.00 sec)
复制
如果值default_password_lifetime正整数N,则表示允许的密码的过期要求,则密码必须每N天进行更改。这个参数是可以动态设置并保存的
MySQL允许限制重复使用以前的密码。可以根据密码更改次数、已用时间或两者来建立重用限制。账户的密码历史由过去分配的密码组成。要全局建立密码重用策略,请使用password_history和password_reuse_interval系统变量。
1.4 用户角色
角色是一组权限的集合。像用户帐户一样,角色可以拥有授予和撤销的权限,可以授予给用户帐户角色,即授予该帐户与每个角色相关的权限。用户被授予角色权限后,该用户拥有该角色所有的权限。
MySQL提供的角色管理功能:
CREATE ROLE、DROP ROLE 角色创建和删除;
GRANT、 REVOKE 用户和角色分配和撤销权限;
SHOW GRANTS 显示用户和角色的权限和角色分配;
SET DEFAULT ROLE 指定哪些帐户角色默认处于活动状态;
SET ROLE 更改当前会话中的活动角色。
CURRENT_ROLE() 显示当前会话中的活动角色。
创建角色,请使用CREATE ROLE:
root@localhost [(none)]> create role app_read,app_write;
Query OK, 0 rows affected (0.01 sec)
root@localhost [mysql]> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| app_read | % |
| app_write | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
| test | localhost |
+------------------+-----------+
7 rows in set (0.00 sec)
复制
为角色分配权限,使用与用户分配权限相同的语法执行:
root@localhost [mysql]> grant create on mysql.* to app_read;
Query OK, 0 rows affected (0.01 sec)
root@localhost [mysql]> show grants for app_read;
+---------------------------------------------+
| Grants for app_read@% |
+---------------------------------------------+
| GRANT USAGE ON *.* TO `app_read`@`%` |
| GRANT CREATE ON `mysql`.* TO `app_read`@`%` |
+---------------------------------------------+
2 rows in set (0.00 sec)
复制
撤消角色或角色权限
正如可以授权某个用户的角色一样,可以从账户中撤销这些角色:
root@localhost [mysql]> revoke create on mysql.* from app_read;
Query OK, 0 rows affected (0.00 sec)
root@localhost [mysql]> show grants for app_read;
+--------------------------------------+
| Grants for app_read@% |
+--------------------------------------+
| GRANT USAGE ON *.* TO `app_read`@`%` |
+--------------------------------------+
1 row in set (0.00 sec)
复制
REVOKE可以用于角色修改角色权限。这不仅影响角色本身权限,还影响任何授予该角色的用户权限。从角色中撤销权限会影响到该角色中任何用户的权限
删除角色
要删除角色,请使用DROP ROLE:
root@localhost [mysql]> drop role app_read,app_write;
Query OK, 0 rows affected (0.00 sec)
复制
删除角色会从授权它的每个帐户中撤销该角色。
最后我们来谈谈操作系统认证:
在ORACLE、SQL Server等商业数据库中,都提供了两种认证方式:一种是操作系统身份认证,另一种是数据库身份认证。在最新的MySQL8.0版本中,MySQL也引入了操作系统身份认证。也是基于插件进行的验证。
安装插件:
root@localhost [mysql]> install plugin auth_socket SONAME 'auth_socket.so';
Query OK, 0 rows affected (0.00 sec)
复制
创建数据库用户,必须为localhost
root@localhost [(none)]> create user test@'localhost' identified with auth_socket;
Query OK, 0 rows affected (0.00 sec)
复制
创建一个同名的操作系统用户
[root@Tdongkf ~]# useradd test
复制
切换到test用户,直接登录即可,不用输入密码
[root@Tdongkf ~]# su - test
Last login: Wed Feb 3 16:34:03 CST 2021 on pts/0
[test@Tdongkf ~]$ mysql -utest --socket=/mysql/my3307/mysql.sock
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 23
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
test@localhost [(none)]> select user();
+----------------+
| user() |
+----------------+
| test@localhost |
+----------------+
1 row in set (0.00 sec)
test@localhost [(none)]>
复制
哈哈,终于不用密码就可以直接登录数据库了。
在其它用户下试试:
[mysql@Tdongkf ~]$ mysql -utest --socket=/mysql/my3307/mysql.sock
ERROR 1698 (28000): Access denied for user 'test'@'localhost'
[mysql@Tdongkf ~]$
复制
报错了,看来不行。
如果我们希望操作系统用户和数据库用户不一样呢?可以手动指定操作系统用户
root@localhost [(none)]> alter user test@'localhost' identified with auth_socket as 'mysql';
Query OK, 0 rows affected (0.00 sec)
复制
再次用mysql用户登录试试:
[mysql@Tdongkf ~]$ id
uid=510(mysql) gid=510(mysql) groups=510(mysql)
[mysql@Tdongkf ~]$ mysql -utest --socket=/mysql/my3307/mysql.sock
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 27
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
test@localhost [(none)]>
复制
mysql操作系统用户可以正常登录了,解决了操作系统用户和登录数据库的用户不一致的问题。
总结,MySQL通过操作系统认证、系统用户与普通用户的分类、权限新增、角色引入等,实现了用户管理的多样化和精细化,可以更好地实现权限分离。

完
=end=