角色就是一个权限的集合。
角色名称
格式
- ‘user_name’@’host_name’
- 与账户名称类似
- host_name 部分可以省略,默认为
%
- user_name 和 host_name 可以不使用引号,除非包含特殊字符,如
-
或%
- user_name 不能为空
与账户名对比
- 不同点
- user 部分不能为空,所以不支持匿名角色
- host 部分不支持通配符
%
- host 部分不支持子网掩码
- 账户名不允许为 CURRENT_USER()
- 相同点
- mysql.user 中,某行数据可以同时充当账户和角色名
- 账户和角色信息都保存在 mysql.user 表中
- 通常仅使用 user_name 部分指定角色名称,host_name 部分隐式的指定为
%
- mysql.user 中,某行数据可以同时充当账户和角色名
使用角色
功能列表
-
创建和删除角色
- CREATE ROLE
- DROP ROLE
- 授权和回收权限
- GRANT
- REVOKE
- 显示账户和角色的分配情况
- SHOW GRANTS
- 指定默认角色
- SET DEFAULT ROLE
- 更改当前会话中的活动角色
- SET ROLE
- 显示当前会话中活动的角色
- CURRENT_ROLE()
- 定义强制性角色并激活
- 系统变量 mandatory_roles 和 activate_all_roles_on_login
创建角色和授予权限
- 创建角色
mysql> create role app_developer,app_read,app_writer;
- 角色创建之后会被锁定 (角色锁定后,无法进行身份验证) ,没有密码,并且会分配一个默认的身份认证插件
mysql> select user,host,plugin,account_locked from mysql.user where host = '%'; +---------------+------+-----------------------+----------------+ | user | host | plugin | account_locked | +---------------+------+-----------------------+----------------+ | app_developer | % | caching_sha2_password | Y | | app_read | % | caching_sha2_password | Y | | app_writer | % | caching_sha2_password | Y | +---------------+------+-----------------------+----------------+
- 角色的属性可以通过 ALTER USER 语句修改,但是需要 CREATE USER 权限
- 角色创建之后会被锁定 (角色锁定后,无法进行身份验证) ,没有密码,并且会分配一个默认的身份认证插件
-
分配权限
mysql> grant all on zabbix.* to app_developer; mysql> grant insert,update,delete on zabbix.* to app_write; mysql> grant insert,update,delete on zabbix.* to app_writer;
- 与账户分配权限的语法相同
- 创建账户
mysql> create user dev1@localhost identified by 'dev1'; mysql> create user read_user1@localhost identified by 'read_user1'; mysql> create user read_user2@localhost identified by 'read_user2'; mysql> create user rw_user1@localhost identified by 'rw_user1';
- 为账户分配角色
mysql> grant app_developer to dev1@localhost; mysql> grant app_read to read_user1@localhost,read_user2@localhost; mysql> grant app_writer to rw_user1@localhost;
- 有 ON 的是分配权限
- 没有 ON 的是分配角色
- 检查角色权限
mysql> show grants for dev1@localhost; +-------------------------------------------------+ | Grants for dev1@localhost | +-------------------------------------------------+ | GRANT USAGE ON *.* TO `dev1`@`localhost` | | GRANT `app_developer`@`%` TO `dev1`@`localhost` | +-------------------------------------------------+ 2 rows in set (0.00 sec) mysql> show grants for dev1@localhost using app_developer; +----------------------------------------------------------+ | Grants for dev1@localhost | +----------------------------------------------------------+ | GRANT USAGE ON *.* TO `dev1`@`localhost` | | GRANT ALL PRIVILEGES ON `zabbix`.* TO `dev1`@`localhost` | | GRANT `app_developer`@`%` TO `dev1`@`localhost` | +----------------------------------------------------------+
- 使用 USING + 角色名称,可以显示角色的权限。
定义强制性角色
强制性角色,会被授予所有用户,无需明确指定账户。
- 系统变量
通过这两个系统变量配置的强制性角色,无法使用
show grants for 账户名
查看账户权限。- mandatory_roles
- 指定强制性角色
- 需要动态权限
- ROLE_ADMIN
- SYSTEM_VARIABLES_ADMIN
- 限制
- 此变量指定的强制性角色不能通过 REVOKE、DROP ROLE 或 DROP USER 收回
- 此变量中的角色不能拥有 SYSTEM_USER 权限,否则会报错。
- 这是为了避免将会话设为系统会话
- 如果此变量指定的角色不在 mysql.user 系统表中,则不会将该角色授予用户。
- 如果角色是后来创建的,还需要 FLUSH PRIVILEGES
- activate_all_roles_on_login
- 强制性角色,在激活前不会生效,需要使用此变量激活
- 动态设置的角色是激活状态
- 此外,还需将角色设置为默认角色
- 默认是禁用状态。
- mandatory_roles
- 配置方法
- 修改配置文件 /etc/my.cnf
[mysqld] mandatory_roles='role1,role2@localhost,r3@%.example.com' activate_all_roles_on_login = on
- 持久化设置系统变量
SET PERSIST mandatory_roles = 'role1,role2@localhost,r3@%.example.com'; set persist activate_all_roles_on_login=on;
- 修改配置文件 /etc/my.cnf
激活角色
- 查看角色的活动状态
mysql> select current_role(); +----------------+ | current_role() | +----------------+ | NONE | +----------------+
- 设置默认激活角色
- 设置方法
- 动态设置连接时默认激活的角色
mysql> set default role all to dev1@localhost, read_user1@localhost, read_user2@localhost, rw_user1@localhost;
- 启动时在配置文件中设置系统变量
- activate_all_roles_on_login
- 动态设置连接时默认激活的角色
- 当使用 rw_user1 连接时,查看当前角色的活动状态
mysql> select current_role(); +------------------+ | current_role() | +------------------+ | `app_writer`@`%` | +------------------+
- 设置方法
- 在会话中更改活动角色
为 rw_user1 赋予两个角色:app_read 和 app_writer,然后激活角色。
mysql> grant app_read, app_writer to rw_user1@localhost; mysql> set default role all to rw_user1@localhost;
通过 SET ROLE 语句可以修改会话中的角色状态。
mysql> select current_role(); +---------------------------------+ | current_role() | +---------------------------------+ | `app_read`@`%`,`app_writer`@`%` | +---------------------------------+ mysql> set role none; select current_role(); +----------------+ | current_role() | +----------------+ | NONE | +----------------+ mysql> set role all except app_writer; select current_role(); +----------------+ | current_role() | +----------------+ | `app_read`@`%` | +----------------+ mysql> set role default; select current_role(); +---------------------------------+ | current_role() | +---------------------------------+ | `app_read`@`%`,`app_writer`@`%` | +---------------------------------+
回收角色和权限
- 回收角色和权限
mysql> revoke app_read from read_user1@localhost; mysql> revoke select on zabbix.* from app_read;
- 系统变量 mandatory_roles 指定的强制性角色,不能通过 REVOKE、DROP ROLE 或 DROP USER 收回。
- 验证
mysql> show grants for app_read; +--------------------------------------+ | Grants for app_read@% | +--------------------------------------+ | GRANT USAGE ON *.* TO `app_read`@`%` | +--------------------------------------+
- 恢复角色的权限 (重新授权)
mysql> grant select on zabbix.* to app_read; mysql> show grants for app_read; +----------------------------------------------+ | Grants for app_read@% | +----------------------------------------------+ | GRANT USAGE ON *.* TO `app_read`@`%` | | GRANT SELECT ON `zabbix`.* TO `app_read`@`%` | +----------------------------------------------+
删除角色
mysql> drop role app_read,app_writer;
mysql> show grants for rw_user1@localhost;
+----------------------------------------------+
| Grants for rw_user1@localhost |
+----------------------------------------------+
| GRANT USAGE ON *.* TO `rw_user1`@`localhost` |
+----------------------------------------------+
Note: 删除角色后,角色对应的账户的权限也恢复默认状态。
- 系统变量 mandatory_roles 指定的强制性角色,不能通过 REVOKE、DROP ROLE 或 DROP USER 收回。
用户和角色的互换性
- 可以将用户/角色授予用户,或将用户/角色授予角色,概括来说,就是可以将用户看作角色
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';
- 查看
mysql> SHOW GRANTS FOR 'u2' USING 'u1', 'r1'; +-------------------------------------+ | Grants for u2@% | +-------------------------------------+ | GRANT USAGE ON *.* TO `u2`@`%` | | GRANT SELECT ON `db1`.* TO `u2`@`%` | | GRANT SELECT ON `db2`.* TO `u2`@`%` | | GRANT `u1`@`%`,`r1`@`%` TO `u2`@`%` | +-------------------------------------+ mysql> SHOW GRANTS FOR 'r2' USING 'u1', 'r1'; +-------------------------------------+ | Grants for r2@% | +-------------------------------------+ | GRANT USAGE ON *.* TO `r2`@`%` | | GRANT SELECT ON `db1`.* TO `r2`@`%` | | GRANT SELECT ON `db2`.* TO `r2`@`%` | | GRANT `u1`@`%`,`r1`@`%` TO `r2`@`%` | +-------------------------------------+
- 将老的账户作为角色授予给其他用户
-- 创建账户 CREATE USER 'old_app_dev'@'localhost' IDENTIFIED BY 'old_app_devpass'; GRANT ALL ON old_app.* TO 'old_app_dev'@'localhost'; -- 修改密码 ALTER USER 'old_app_dev'@'localhost' IDENTIFIED BY 'new_password'; -- 锁定账户 ALTER USER 'old_app_dev'@'localhost' ACCOUNT LOCK; -- 将老的账户作为角色授予其他账户 CREATE USER 'new_app_dev1'@'localhost' IDENTIFIED BY 'new_password'; GRANT 'old_app_dev'@'localhost' TO 'new_app_dev1'@'localhost';
- 查看
- 规范
- 角色名加
r_
前缀 - 账户名加
u_
前缀
- 角色名加