MySQL8 基于角色的权限管理

MySQL8新增了角色(role)的概念,使账号权限的管理,更加灵活方便。所谓角色,就是一些权限的集合。然后再把该集合授权给某个账户(往往是某一批账户,因为账号会绑定IP,不同的IP,虽然账号名相同被视为不同账号),这样当我们需要对这些账号减少或增加权限时,只需要修改权限集合(role)即可,不用单个账号多次修改。这确实使DBA的运维轻松了不少。

下面我们看下role是如何使用的。

创建角色

比如开发环境账户需要某库的所有权限,生产环境账号往往需要增删改查这些权限,我们可以单独为这些权限建一个role.如果有读写分离,还可以建两个读和写的role。


create role 'app_dev','app_read','app_write';

mysql8[(none)]>show grants for 'app_dev';

+-------------------------------------+

| Grants for app_dev@%                |

+-------------------------------------+

| GRANT USAGE ON *.* TO `app_dev`@`%` |

+-------------------------------------+

创建角色时同样可以绑定Host(默认%), 即角色名分为name + host两部分,这和账号没有什么区别。

同样创建的角色也和账号一样保存在mysql.user表中。通过查询此表可以看到角色的信息:


mysql8[(none)]>select * from mysql.user;

+-----------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+------------------------------------------------------------------------+------------------+-----------------------+-------------------+----------------+------------------+----------------+------------------------+---------------------+

| Host      | User            | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv | Show_db_priv | Super_priv | Create_tmp_table_priv | Lock_tables_priv | Execute_priv | Repl_slave_priv | Repl_client_priv | Create_view_priv | Show_view_priv | Create_routine_priv | Alter_routine_priv | Create_user_priv | Event_priv | Trigger_priv | Create_tablespace_priv | ssl_type | ssl_cipher | x509_issuer | x509_subject | max_questions | max_updates | max_connections | max_user_connections | plugin                | authentication_string                                                  | password_expired | password_last_changed | password_lifetime | account_locked | Create_role_priv | Drop_role_priv | Password_reuse_history | Password_reuse_time |

+-----------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+------------------------------------------------------------------------+------------------+-----------------------+-------------------+----------------+------------------+----------------+------------------------+---------------------+

| %        | app_dev          | N          | N          | N          | N          | N          | N        | N          | N            | N            | N        | N          | N              | N          | N          | N            | N          | N                    | N                | N            | N              | N                | N                | N              | N                  | N                  | N                | N          | N            | N                      |          |            |            |              |            0 |          0 |              0 |                    0 | caching_sha2_password |                                                                        | Y                | 2018-06-14 11:27:35  |              NULL | Y              | N                | N              |                  NULL |                NULL |

| %        | app_read        | N          | N          | N          | N          | N          | N        | N          | N            | N            | N        | N          | N              | N          | N          | N            | N          | N                    | N                | N            | N              | N                | N                | N              | N                  | N                  | N                | N          | N            | N                      |          |            |            |              |            0 |          0 |              0 |                    0 | caching_sha2_password |                                                                        | Y                | 2018-06-14 11:27:35  |              NULL | Y              | N                | N              |                  NULL |                NULL |

| %        | app_write        | N          | N          | N          | N          | N          | N        | N          | N            | N            | N        | N          | N              | N          | N          | N            | N          | N                    | N                | N            | N              | N                | N                | N              | N                  | N                  | N                | N          | N            | N                      |          |            |            |              |            0 |          0 |              0 |                    0 | caching_sha2_password |                                                                        | Y                | 2018-06-14 11:27:35  |              NULL | Y              | N                | N              |                  NULL |                NULL |

| %        | repl            | N          | N          | N          | N          | N          | N        | N          | N            | N            | N        | N          | N              | N          | N          | N            | N          | N                    | N                | N            | Y              | N                | N                | N              | N                  | N                  | N             

给角色授权

上面我们建了三个role,但这三个role都只有usage权限,我们还需要对角色进行授权。授权方式与给账号授权是完全一样的。


mysql8[(none)]>grant select , insert,update,delete on test.* to app_dev;

Query OK, 0 rows affected (0.02 sec)

mysql8[(none)]>grant select on test.* to app_read;

Query OK, 0 rows affected (0.10 sec)

mysql8[(none)]>show grants for app_read;

+--------------------------------------------+

| Grants for app_read@%                      |

+--------------------------------------------+

| GRANT USAGE ON *.* TO `app_read`@`%`      |

| GRANT SELECT ON `test`.* TO `app_read`@`%` |

+--------------------------------------------+

2 rows in set (0.00 sec)

mysql8[(none)]>show grants for app_dev;

+-------------------------------------------------------------------+

| Grants for app_dev@%                                              |

+-------------------------------------------------------------------+

| GRANT USAGE ON *.* TO `app_dev`@`%`                              |

| GRANT SELECT, INSERT, UPDATE, DELETE ON `test`.* TO `app_dev`@`%` |

+-------------------------------------------------------------------+

授权后我们看到各角色已经具有了相应的权限。

将角色授权于账号

下面我们创建具体的账号,并将相应的role授权给账号。


mysql8[(none)]>create user dev01 identified with mysql_native_password by 'dev01';

Query OK, 0 rows affected (0.04 sec)

mysql8[(none)]>grant app_dev to dev01;

Query OK, 0 rows affected (0.05 sec)

mysql8[(none)]>show grants for dev01;

+------------------------------------+

| Grants for dev01@%                |

+------------------------------------+

| GRANT USAGE ON *.* TO `dev01`@`%`  |

| GRANT `app_dev`@`%` TO `dev01`@`%` |

+------------------------------------+

我们创建了一个账号dev01,并授权角色app_dev, 执行show grants 查看权限时,看到的是角色,并不是具体的权限。如果要查看具体的权限则需要这样执行show grants.


mysql8[(none)]>show grants for dev01 using app_dev;

+-----------------------------------------------------------------+

| Grants for dev01@%                                              |

+-----------------------------------------------------------------+

| GRANT USAGE ON *.* TO `dev01`@`%`                              |

| GRANT SELECT, INSERT, UPDATE, DELETE ON `test`.* TO `dev01`@`%` |

| GRANT `app_dev`@`%` TO `dev01`@`%`                              |

+-----------------------------------------------------------------+

通过使用using app_dev,会将账号和角色的权限一并显示。

我们给角色app_dev添加create权限


mysql8[(none)]>grant create on test.* to app_dev;

Query OK, 0 rows affected (0.10 sec)

mysql8[(none)]>show grants for dev01 using app_dev;

+-------------------------------------------------------------------------+

| Grants for dev01@%                                                      |

+-------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO `dev01`@`%`                                      |

| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ON `test`.* TO `dev01`@`%` |

| GRANT `app_dev`@`%` TO `dev01`@`%`                                      |

+-------------------------------------------------------------------------+

3 rows in set (0.00 sec)

可以看到给角色添加权限后,dev01账号也具有了create权限。

激活角色

上面的一些列操作貌似完美,dev02账号可以使用了,其实还不行!使用dev01账号登陆:


mysql> show grants for dev01 using app_dev;

+-------------------------------------------------------------------------+

| Grants for dev01@%                                                      |

+-------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO `dev01`@`%`                                      |

| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ON `test`.* TO `dev01`@`%` |

| GRANT `app_dev`@`%` TO `dev01`@`%`                                      |

+-------------------------------------------------------------------------+

3 rows in set (0.00 sec)

mysql> show databases;

+--------------------+

| Database          |

+--------------------+

| information_schema |

+--------------------+

1 row in set (0.01 sec)

发现权限也有,但并看不到test库,什么也无法执行。为什么呢?角色没有被激活


mysql> select current_role()

    -> ;

+----------------+

| current_role() |

+----------------+

| NONE          |

+----------------+

1 row in set (0.00 sec)

执行select current_role()发现是None. 所授权的角色并没有被激活,因此这个账号 还是废柴一个。

对账号激活权限也很简单


mysql8[(none)]>set default role all to dev01;

Query OK, 0 rows affected (0.06 sec)

这样对dev01授予的所有角色都会被激活。再使用dev01登陆就正常访问了。


mysql> show databases;

+--------------------+

| Database          |

+--------------------+

| information_schema |

| test              |

+--------------------+

2 rows in set (0.01 sec)

mysql> select current_role();

+----------------+

| current_role() |

+----------------+

| `app_dev`@`%`  |

+----------------+

1 row in set (0.00 sec)

可以看到当前激活的角色为app_dev.

感觉流程太繁琐了,都授权完了还要激活,但MySQL8 提供已一个参数,可以使角色在账号登陆后自动被激活。


mysql8[(none)]>show global variables like 'activate_all_roles_on_login';

+-----------------------------+-------+

| Variable_name              | Value |

+-----------------------------+-------+

| activate_all_roles_on_login | OFF  |

+-----------------------------+-------+

1 row in set (0.01 sec)

mysql8[(none)]>set global activate_all_roles_on_login=ON;

Query OK, 0 rows affected (0.00 sec)

把activate_all_roles_on_login设置为ON就可以了。


mysql8[(none)]>create user query identified with mysql_native_password by 'query';

Query OK, 0 rows affected (0.04 sec)

mysql8[(none)]>grant app_read to query;

Query OK, 0 rows affected (0.06 sec)

mysql8[(none)]>show grants for query using app_read;

+-----------------------------------------+

| Grants for query@%                      |

+-----------------------------------------+

| GRANT USAGE ON *.* TO `query`@`%`      |

| GRANT SELECT ON `test`.* TO `query`@`%` |

| GRANT `app_read`@`%` TO `query`@`%`    |

+-----------------------------------------+

3 rows in set (0.00 sec)

mysql8[(none)]>exit

使用query账号登陆


mysql> show databases;

+--------------------+

| Database          |

+--------------------+

| information_schema |

| test              |

+--------------------+

2 rows in set (0.00 sec)

mysql> select current_user();

+----------------+

| current_user() |

+----------------+

| query@%        |

+----------------+

1 row in set (0.00 sec)

mysql> select current_role();

+----------------+

| current_role() |

+----------------+

| `app_read`@`%` |

+----------------+

1 row in set (0.00 sec)

可以看到角色已被激活。

角色和账号交互使用

角色和账号没有什么区别,可以把一个账号当做一个角色,将其授权给其它账号。详见MySQL 官方文档


CREATE USER 'u1';

CREATE ROLE 'r1';

GRANT SELECT ON db1.* TO 'u1';

GRANT SELECT ON db2.* TO 'r1';

CREATE USER 'u2';

CREATE ROLE 'r2';

GRANT 'u1', 'r1' TO 'u2';

GRANT 'u1', 'r1' TO 'r2';

这也太灵活了吧? 我惊掉了下巴!

阅读更多

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 几乎任何一个后台,都会涉及到权限管理,哪些人(用户)有能够登陆,能够操作哪些东西(权限)。 基于角色的访问控制方法...
    烤鱼吃辣椒阅读 10,438评论 1 71
  • 有了QQ,将号码发给同事、同学、朋友。 于是,即使多年没见面的人都会或发个短信,或打个电话,或留个言支持我这个新手...
    高小花0218阅读 140评论 0 0
  • 哭的时候没人哄 于是我们学会了坚强 怕的时候没人陪 于是我们学会了勇敢 烦的时候没人倾诉 于是我们学会了承受 累的...
    Mr酵母君阅读 134评论 0 2
  • “奥呦…玩的是王者农药呀…怎么样,玩的咋样?”,中午饭局上一哥们跟另一个手里抱着手机玩游戏的哥们调侃着说道。当下如...
    将军_84fd阅读 421评论 0 0
  • 我是一只小小鸟, 胆小而懦弱。 飞也飞不高, 却拥有无尽的勇气和力量。 这个世间, 嘈杂的声音, 缭乱的节奏。 到...
    阿俊xi阅读 179评论 0 0