Role-based access control,RBAC 基于角色的权限访问控制。

    区别于 MAC (Mandatory access control) 以及 DAC (Discretionary Access Control),RBAC 更为中性且更具灵活性。

    TiDB 的基于角色的访问控制 (RBAC) 系统的实现类似于 MySQL 8.0 的 RBAC 系统,兼容大部分 。

    • 方便用户权限管理,同时修改多个用户的权限。

    • 用户关注场景,角色关注权限。

    • 进行继承,角色可以授予给另外一个角色。

    • TiDB 的权限管理器,构建出了一个邻接表来记录图结构。 在鉴权时,从用户拥有的角色出发,进行深度优先搜索,找到所有与之相关的角色,将这些角色的权限汇总起来,就得到了用户的角色权限。

    • 每个会话 session 中维护了一个 ActiveRole 数组,其中记录着当前哪些角色是启用着,在使用 SET ROLE 时便会对这个数组进行修改,同时权限管理器在用户进行登录时,也会在内存系统表缓存中,找到 default_roles 中记录的默认启用角色,构建出最开始的 ActiveRole 数组。

    主要依赖以下系统表:

    • mysql.user 复用用户表,区别是 Account_Locked 字段,角色的值是 Y,也就是不能登陆.
    • mysql.role_edges 描述了角色和角色,角色和用户之间的授予关系。 例如将角色 r1 授予给 test 后,会出现这样一条记录:
    1. | FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
    2. +-----------+-----------+---------+---------+-------------------+
    3. | % | r1 | % | test | N |
    4. +-----------+-----------+---------+---------+-------------------+
    • mysql.default_roles 记录每个用户默认启用的角色,启用后的角色才能生效。
    1. +------+------+-------------------+-------------------+
    2. | HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
    3. +------+------+-------------------+-------------------+
    4. | % | test | % | r_1 |
    5. +------+------+-------------------+-------------------+
    • 创建角色 r_1,r_2,可以一次创建多个,示例:
    1. CREATE ROLE `r_1`@`%`, `r_2`@`%`;
    • 设置 r_1 为只读角色:
    • 将 r_1 角色授予用户 test@’%’:
    1. grant r_1 to test@'%';
    • 启用默认角色,在登陆时,默认启用的角色会被自动启用:
    1. SET DEFAULT ROLE 'r_1';
    • 启用当前session角色,仅对当前session生效:
    1. SET ROLE 'r_1';
    • 查看用户角色:
    • 查看用户角色权限:
    1. TiDB > SHOW GRANTS FOR 'test'@'%' USING 'r_1';
    2. | Grants for test@% |
    3. +--------------------------------------+
    4. | GRANT USAGE ON *.* TO 'test'@'%' |
    5. | GRANT Select ON test.* TO 'test'@'%' |
    6. | GRANT 'r_1'@'%' TO 'test'@'%' |
    7. +--------------------------------------+
    • 收回角色:
    1. REVOKE 'r_1' FROM 'test'@'%', 'root'@'%';
    1. #创建角色 reader
    2. root@127.0.0.1:(none)>create role reader@'%';
    3. Query OK, 0 rows affected (0.012 sec)
    4. #设置角色 reader 只读 mysql.role_edges 权限
    5. root@127.0.0.1:mysql>grant select on mysql.role_edges to reader'%';
    6. Query OK, 0 rows affected (0.017 sec)
    7. #创建用户 bi_user
    8. root@127.0.0.1:(none)>create user bi_user@'%';
    9. Query OK, 0 rows affected (0.011 sec)
    10. #将只读角色 reader 授予 bi_user 用户
    11. root@127.0.0.1:mysql>grant reader to bi_user'%';
    12. Query OK, 0 rows affected (0.014 sec)
    13. # bi_user 登录查看无数据权限
    14. bi_user@127.0.0.1:(none)>show databases;
    15. +--------------------+
    16. | Database |
    17. +--------------------+
    18. | INFORMATION_SCHEMA |
    19. +--------------------+
    20. 1 row in set (0.000 sec)
    21. #查看当前登录用户 bi_user 当前未启用角色
    22. bi_user@127.0.0.1:(none)>SELECT CURRENT_ROLE();
    23. +----------------+
    24. | CURRENT_ROLE() |
    25. | |
    26. +----------------+
    27. 1 row in set (0.000 sec)
    28. #在当前 session 中启用 bi_user 的 reader 角色
    29. bi_user@127.0.0.1:(none)>set role reader;
    30. Query OK, 0 rows affected (0.000 sec)
    31. #查看 bi_user 当前被启用的角色
    32. bi_user@127.0.0.1:(none)>SELECT CURRENT_ROLE();
    33. +----------------+
    34. | CURRENT_ROLE() |
    35. +----------------+
    36. | `reader`@`%` |
    37. +----------------+
    38. 1 row in set (0.000 sec)
    39. #当前登录用户 bi_user 查看 mysql 库中有权限的表
    40. bi_user@127.0.0.1:mysql>select * from role_edges;
    41. +-----------+-----------+---------+---------+-------------------+
    42. | FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
    43. +-----------+-----------+---------+---------+-------------------+
    44. | % | reader | % | bi_user | N |
    45. +-----------+-----------+---------+---------+-------------------+
    46. 1 row in set (0.000 sec)
    47. #当前登录用户 bi_user 执行 delete 表报错,权限校验失败
    48. bi_user@127.0.0.1:mysql>delete from role_edges;
    49. ERROR 1105 (HY000): privilege check fail
    50. #当前登录用户 bi_user 执行查询其他表报错
    51. bi_user@127.0.0.1:mysql>select * from user;
    52. ERROR 1142 (42000): SELECT command denied to user 'bi_user'@'127.0.0.1' for table 'user'
    53. #重新登录 bi_user 权限已经失效
    54. bi_user@127.0.0.1(none)>use mysql
    55. ERROR 1044 (42000): Access denied for user 'bi_user'@'%' to database 'mysql'

    本小节介绍了 RBAC 的原理和使用方式,企业用户可以用 RBAC 构建出一套灵活的权限管理机制。下一节中将介绍 TiDB 的另一种身份验证方式——证书验证。