MySQL 用户与权限精细化管理实战:从创建到权限回收全流程

用户和权限管理

应用场景数据库服务安装成功后默认有一个 root 用户,可以新建和操纵数据库服务中管理的所有数据库。在真实的使用过程中,通常每个应用对应着一个数据库,我们只希望某个用户只能操纵和管理当前应用对应的那个数据库,而不能操纵和管理其他应用的数据库,这时就可以添加一个用户并指定用户的权限

如上图所示:

  • root 可以访问和操纵所有的数据库:DB1, DB2, DB3, DB4

  • 普通用户 1 只能访问和操纵数据库 DB1

  • 普通用户 2 只能访问和操纵数据库 DB3

  • 只读用户 1 只能访问数据库 DB3

  • 只读用户 2 只能访问数据库 DB4

用户

3.1 查看用户

MySQL 的用户信息保存在 mysql 系统数据库的 user 表中,可以通过 Select 语句查看,如下所示:

复制代码
# 选择数据库
mysql> use mysql
Database changed

# 查看所有的表
mysql> show tables;

# 查看表结构
mysql> desc user;

# 查询user表中的记录
mysql> select host, user, authentication_string from user;
+------------------+------------------+------------------------------------------------------------------------+
| host             | user             | authentication_string                                                  |
+------------------+------------------+------------------------------------------------------------------------+
| localhost        | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost        | mysql.session    | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost        | mysql.sys        | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost        | root             | $A$005$4*/zI3, S2!90SH5k8QgT2Bo6ePFBOP6cbLlgLXQTasCSS8WzBDdXrC |
+------------------+------------------+------------------------------------------------------------------------+
4 rows in set (0.00 sec)
  • host: 允许登录的主机,相当于白名单,如果是localhost,表示只能从本机登陆

  • user: 用户名

  • *_priv: 用户拥有的权限

  • authentication_string: 加密后的用户密码

    复制代码
    desc user;

注意:

复制代码
select * from user\G;

3.2 创建用户

3.2.1 语法
复制代码
CREATE USER [IF NOT EXISTS] 'user_name'@'host_name' IDENTIFIED BY 'auth_string';

user_name: 用户名,用单引号包裹,区分大小写host_name: 主机或 IP (段),用单引号包裹auth_string: 真实密码,有密码策略不允许使用简单密码

3.2.2 注意事项
  • 如果不指定host_name 相当于 'user_name'@'%'% 表示所有主机都可以连接到数据库,强烈建议不要这样设置,因为会导致严重的安全问题
  • user_name 和 host_name 分别用单引号包裹,如果写成 'user_name@host_name',相当于 'user_name@host_name'@'%'
  • host_name 可以通过子网掩码设置主机范围
    • 198.0.0.0/255.0.0.0: A 段网络中的任意一台主机
    • 198.51.0.0/255.255.0.0: 198.51 B 段网络中的任意一台主机
    • 198.51.100.0/255.255.255.0: 198.51.100 C 段网络中的任意一台主机
    • 198.51.100.1: 只包含特定 IP 地址的主机
  • 从 MySQL 8.0.23 开始,指定为 IPv4 地址的主机值可以使用 CIDR 表示法写入,例如 198.51.100.44/24
  • 允许在 IP 地址中使用 % 通配符,比如,主机值 '%' 匹配任何主机名,198.51.100.% 匹配 198.51.100 C 段网络中的任何主机。MySQL 8.0.35 中已弃用,以后可能会删除
3.2.3 示例
复制代码
# 添加一个名为bit的新用户,允许从本机登录
mysql> create user 'bit'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.02 sec)


# 添加一个名为bit1的新用户,允许从192.168.1.1/24网段登录
mysql> create user 'bit1'@'192.168.1.1/24' identified by '123456';
Query OK, 0 rows affected (0.02 sec)


# 查询,添加成功
mysql> select host, user, authentication_string from user\G
*************************** 1. row ***************************
        host: 192.168.1.36/24
        user: bit1
authentication_string: LYkbuBpcAPQIf2JJS8cJe4u.5ce6UPmQ0IU2phfmfKQ7-:%
*************************** 2. row ***************************
        host: localhost
        user: bit
authentication_string: $A$005$P+Pe6Ht 5$SxK0oxjZgt8EUt2nYzalIHaP6f0aSw2BzHeEafnFzB
*************************** 3. row ***************************
        host: localhost
        user: mysql.infoschema
authentication_string: $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 4. row ***************************
        host: localhost
        user: mysql.session
authentication_string: $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 5. row ***************************
        host: localhost
        user: mysql.sys
authentication_string: $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 6. row ***************************
        host: localhost
        user: root
authentication_string: $A$005$4*/zI3zS2!90SH5k8QgT2Bo6ePFBOP6cbLlgLXQTasCSS8WzBDdXrC
6 rows in set (0.00 sec)

新用户登录

复制代码
# 使用新用户登录
C:\Users\bit>mysql -ubit -p
Enter password: ******
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.39 MySQL Community Server - GPL

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

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.
3.2.4

3.3 修改密码

3.3.1 语法
复制代码
# 为指定用户设置密码【推荐】
ALTER USER 'user_name'@'host_name' IDENTIFIED BY 'auth_string';

# 为指定用户设置密码
SET PASSWORD FOR 'user_name'@'host_name' = 'auth_string';

# 为当前登录用户设置密码
SET PASSWORD = 'auth_string';
3.3.2 示例
复制代码
# 以root身份登录,为'bit'@'localhost'用户重置密码
mysql> ALTER USER 'bit'@'localhost' IDENTIFIED BY '987654';
Query OK, 0 rows affected (0.02 sec)

# 以root身份登录,为'bit'@'localhost'用户重置密码
mysql> SET PASSWORD FOR 'bit'@'localhost' = '123456';
Query OK, 0 rows affected (0.01 sec)

# 以bit用户登录,并确认当前登录用户,USER()与CURRENT_USER()是同义词
mysql> select USER();
+----------------+
| USER()         |
+----------------+
| bit@localhost  |
+----------------+
1 row in set (0.00 sec)

# 修改当前登录用户的密码
mysql> SET PASSWORD = '111111';
Query OK, 0 rows affected (0.02 sec)

3.4 删除用户

3.4.1 语法
复制代码
DROP USER [IF EXISTS] 'user_name'@'host_name' [, ...];
  • [IF EXISTS]可选参数,表示 "如果用户存在就删除,不存在也不报错"(避免用户不存在时触发错误)。
  • 'user_name'@'host_name'必填 ,要删除的用户(user_name)和对应的登录主机(host_name),需用单引号包裹。
  • [, ...]可选,表示可以同时删除多个用户,用逗号分隔即可。

示例:

复制代码
-- 同时删除2个用户:hanyulong@localhost、test@192.168.1.1
DROP USER IF EXISTS 'hanyulong'@'localhost', 'test'@'192.168.1.1';
3.4.2 示例
复制代码
# 删除用户'bit1'@'192.168.1.1/24'
mysql> drop user 'bit1'@'192.168.1.1/24';
Query OK, 0 rows affected (0.01 sec)

# 删除成功,查询用户表确认
mysql> select host, user, authentication_string from user;
+-----------+------------------+------------------------------------------------------------------------+
| host      | user             | authentication_string                                                  |
+-----------+------------------+------------------------------------------------------------------------+
| localhost | bit              | $A$005$P+Pe6Ht 5$SxK0oxjZgt8EUt2nYzalIHaP6f0aSw2BzHeEafnFzB           |
| localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.session    | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.sys        | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | root             | $A$005$4*/zI3zS2!90SH5k8QgT2Bo6ePFBOP6cbLlgLXQTasCSS8WzBDdXrC        |
+-----------+------------------+------------------------------------------------------------------------+
5 rows in set (0.00 sec)

权限管理

权限与授权

  • MySQL 内置支持的权限列表
1.1 给用户授权

刚创建的用户没有任何权限,需要给他授权,如下所示:

复制代码
mysql> select user();
+----------------+
| user()         |
+----------------+
| bit@localhost  |
+----------------+
1 row in set (0.00 sec)

# 看不到其他的数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)
1.1.1 语法
复制代码
grant priv_type[, priv_type ...] on priv_level
to 'user_name'@'host_name' [WITH GRANT OPTION]
  • priv_type:根据类型,参考根据表 4.1 中的 Privilege 列
  • priv_level*.*|db_name.*|db_name.tbl_name|tbl_name,比如*.*表示所有数据库下的所有表
  • 'user_name'@'host_name':指定用户
  • [WITH GRANT OPTION]:可选,允许用户将自己的权限授权给其它用户
1.1.2 示例
  • bit@localhost用户授权于java01数据库的select权限

    授权

    mysql> grant select on java01.* to 'bit'@'localhost';
    Query OK, 0 rows affected (0.04 sec)

    查看数据库,可以看到java01

    mysql> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | java01 |
    | performance_schema |
    +--------------------+
    3 rows in set (0.00 sec)

    选择数据库

    mysql> use java01
    Database changed

    查看所有表

    mysql> show tables;
    +-------------------+
    | Tables_in_java01 |
    +-------------------+
    | account |
    | class |
    | course |
    | emp |
    | exam |
    | for_delete |
    | score |
    | student |
    | student1 |
    | t_check |
    | t_recored |
    | t_recored_old |
    | t_truncate |
    | users |
    | v_student_score |
    | v_student_score_v1|
    | v_student_total_points |
    +-------------------+
    17 rows in set (0.00 sec)

    查询数据

    mysql> select * from student;
    +----+-----------+--------+-----+--------+------------+----------+
    | id | name | sno | age | gender | enroll_date| class_id |
    +----+-----------+--------+-----+--------+------------+----------+
    | 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
    | 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
    | 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
    | 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
    | 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
    | 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
    | 7 | 李逵 | 200003 | 18 | 1 | 2000-09-01 | 2 |
    | 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
    +----+-----------+--------+-----+--------+------------+----------+
    8 rows in set (0.02 sec)

    写入一条数据时失败,因为没有授权写入权限

    mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
    ERROR 1142 (42000): INSERT command denied to user 'bit'@'localhost' for table 'student'

  • 查看bit@localhost用户权限,USAGE表示在指定的priv_level上没有权限

    mysql> show grants for 'bit'@'localhost';
    +---------------------------------------------+
    | Grants for bit@localhost |
    +---------------------------------------------+
    | GRANT USAGE ON . TO 'bit'@'localhost' |
    | GRANT SELECT ON java01.* TO 'bit'@'localhost' |
    +---------------------------------------------+
    2 rows in set (0.00 sec)

  • bit@localhost用户授权于java01数据库的所有权限

    ALL为所有权限

    mysql> grant ALL on java01.* to 'bit'@'localhost';
    Query OK, 0 rows affected (0.01 sec)

    查看用户权限

    mysql> show grants for 'bit'@'localhost';
    +---------------------------------------------+
    | Grants for bit@localhost |
    +---------------------------------------------+
    | GRANT USAGE ON . TO 'bit'@'localhost' |
    | GRANT ALL PRIVILEGES ON java01.* TO 'bit'@'localhost' |
    +---------------------------------------------+
    2 rows in set (0.00 sec)

    插入一条新记录

    mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
    ERROR 1142 (42000): INSERT command denied to user 'bit'@'localhost' for table 'student'

    不成功说明权限没有生效,需要刷新权限,如果还不成功可以重新登录

    mysql> flush privileges;
    Query OK, 0 rows affected (0.01 sec)

    重新执行插入操作

    mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
    Query OK, 1 row affected (0.02 sec)

    查看记录

    mysql> select * from student;
    +----+-----------+--------+-----+--------+------------+----------+
    | id | name | sno | age | gender | enroll_date| class_id |
    +----+-----------+--------+-----+--------+------------+----------+
    | 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
    | 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
    | 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
    | 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
    | 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
    | 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
    | 7 | 李逵 | 200003 | 18 | 1 | 2000-09-01 | 2 |
    | 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
    | 12 | test | 500001 | 18 | 1 | 2000-06-08 | 1 | # 新记录写入成功
    +----+-----------+--------+-----+--------+------------+----------+
    9 rows in set (0.00 sec)

    删除操作

    mysql> delete from student where id = 12;
    Query OK, 1 row affected (0.01 sec)

    删除成功

    mysql> select * from student;
    +----+-----------+--------+-----+--------+------------+----------+
    | id | name | sno | age | gender | enroll_date| class_id |
    +----+-----------+--------+-----+--------+------------+----------+
    | 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
    | 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
    | 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
    | 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
    | 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
    | 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
    | 7 | 李逵 | 200003 | 18 | 1 | 2000-09-01 | 2 |
    | 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
    +----+-----------+--------+-----+--------+------------+----------+
    8 rows in set (0.00 sec)

1.2 回收权限
1.2.1 语法
复制代码
REVOKE [权限类型] ON [权限范围] FROM '用户名'@'主机名';

REVOKE [IF EXISTS] priv_type[, priv_type] ... ON priv_level
FROM 'user_name'@'host_name' [, 'user_name'@'host_name'] ...

示例:

复制代码
-- 回收插入权限
REVOKE INSERT ON java01.* FROM 'bit'@'localhost';
-- 刷新权限使其生效
FLUSH PRIVILEGES;

注意:

  1. 必须刷新权限 执行 REVOKE 后,需要运行 FLUSH PRIVILEGES; 让权限变更立即生效,否则用户的现有连接可能还能继续使用旧权限。
1.2.2 示例
  • 回收bit@localhost用户对于java01数据库的权限

    mysql> REVOKE all on *. from 'bit'@'localhost';
    Query OK, 0 rows affected (0.01 sec)

    刷新权限

    mysql> flush privileges;
    Query OK, 0 rows affected (0.01 sec)

    查看权限,没有任何授权

    mysql> show grants for 'bit'@'localhost';
    +---------------------------------------------+
    | Grants for bit@localhost |
    +---------------------------------------------+
    | GRANT USAGE ON . TO bit@localhost |
    +---------------------------------------------+
    1 row in set (0.00 sec)

    查看所有数据库,没有可以访问的库

    mysql> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | performance_schema |
    +--------------------+
    2 rows in set (0.00 sec)

相关推荐
lzhdim2 小时前
C#应用程序取得当前目录和退出
开发语言·数据库·microsoft·c#
last_zhiyin2 小时前
Oracle sql tuning guide 翻译 Part 4-1 --- 连接操作(Joins)
数据库·sql·oracle
老华带你飞2 小时前
农产品销售管理|基于springboot农产品销售管理系统(源码+数据库+文档)
数据库·vue.js·spring boot
电商API&Tina2 小时前
跨境电商速卖通(AliExpress)数据采集与 API 接口接入全方案
大数据·开发语言·前端·数据库·人工智能·python
-suiyuan-2 小时前
sqli-labs靶场1~2笔记
数据库·sql
瀚高PG实验室2 小时前
在Highgo DB 中创建MySQL兼容函数datediff
数据库·mysql·瀚高数据库
bing.shao2 小时前
FerretDB 替换MongoDB符合信创要求
数据库·mongodb
Han_coding12083 小时前
从原理到实战:基于游标分页解决深分页问题(附源码方案)
java·服务器·数据库·spring boot·spring cloud·oracle
今晚务必早点睡3 小时前
Redis——快速入门第一课:了解redis
数据库·redis·缓存