概述
文章目录
- 使用角色
- 创建角色并为其授予权限
- 定义强制性角色
- 检查角色权限
- 激活角色
- 撤销角色或角色权限
- 删除角色
使用角色
MySQL 角色是一个命名的权限集合。与用户帐户一样,角色也可以被授予或撤消权限。
用户帐户可以被授予角色,角色将授予帐户与每个角色关联的权限。这允许将一组权限分配给帐户,并提供了授予单独权限的方便替代方案。
以下列表总结了 MySQL 提供的角色管理功能:
-
CREATE ROLE
和 DROP ROLE 创建和删除角色。 -
GRANT
和REVOKE
为账户和角色分配权限和撤销权限 -
SHOW GRANTS
显示用户帐户分配的角色以及角色的权限。 -
SET DEFAULT ROLE
默认情况下制定哪些账户角色是活跃的。 -
SET ROLE
更改当前会话中活跃的角色。 -
CURRENT_ROLE()
函数显示当前会话中的活跃角色。 -
当用户登录到服务器时,
mandatory_roles
和activate_all_roles_on_login
系统变量允许定义强制角色和自动激活授予的角色。
创建角色并为其授予权限
考虑这个场景:
- 应用程序使用名为
app_db
的数据库。 - 与应用程序相关联的帐户可以是创建和维护应用程序的开发人员的帐户,也可以是与应用程序交互的用户的帐户。
- 开发人员需要完全访问数据库。有些用户只需要读权限,有些用户需要读/写权限。
若要避免单独向多个用户帐户授予权限,请创建角色作为所需权限集的名称。这使得通过授予适当的角色,可以很容易地向用户帐户授予所需的权限。
要创建角色,请使用 CREATE ROLE
语句:
CREATE ROLE 'app_developer', 'app_read', 'app_write';
角色名称与用户帐户名称非常相似,由'user_name'@'host_name'
格式的用户部分和主机部分组成。主机部分,如果省略,默认为 '%'
。用户和主机部分可以不加引号,除非它们包含特殊字符,例如 -
或 %
。与帐户名称不同,角色名称的用户部分不能为空。
要给角色分配权限,执行GRANT
语句,语法与给用户帐户分配权限相同:
GRANT ALL ON app_db.* TO 'app_developer';
GRANT SELECT ON app_db.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';
现在假设您需要一个开发者帐户、两个需要只读访问权限的用户帐户和一个需要读/写访问权限的用户帐户。使用 CREATE USER
创建账户:
CREATE USER 'dev1'@'localhost' IDENTIFIED BY 'dev1pass';
CREATE USER 'read_user1'@'localhost' IDENTIFIED BY 'read_user1pass';
CREATE USER 'read_user2'@'localhost' IDENTIFIED BY 'read_user2pass';
CREATE USER 'rw_user1'@'localhost' IDENTIFIED BY 'rw_user1pass';
为用户账户分配角色:
GRANT 'app_developer' TO 'dev1'@'localhost';
GRANT 'app_read' TO 'read_user1'@'localhost', 'read_user2'@'localhost';
GRANT 'app_read', 'app_write' TO 'rw_user1'@'localhost';
rw_user1
帐户的GRANT
语句授予读写角色,这些角色组合起来提供所需的读写权限。
授予帐户角色的 GRANT
语法与授予权限的语法不同:分配权限有ON
子句,分配角色没有ON
语句。由于语法不同,您不能在同一语句中混合分配权限和角色。从 MySQL 8.0.16 开始,角色不能授予匿名用户。
角色在创建时被锁定,没有密码,并且被分配了默认的身份验证插件(具有全局CREATE USER
权限的用户可以稍后使用ALTER USER
语句更改这些角色属性)
锁定时,角色不能用于身份验证。如果未锁定,则可以使用角色进行认证。这是因为角色和用户都是授权标识符,它们有很多共同点,但几乎没有区别。
定义强制性角色
可以通过在mandatory_roles
系统变量的值中命名角色,将它们指定为强制角色。服务器将强制角色视为授予所有用户的角色,因此不需要显式地授予任何帐户。
要在服务器启动时指定强制角色,请在服务器 my.cnf
文件中定义强制角色:
[mysqld]
mandatory_roles='role1,role2@localhost,r3@%.example.com'
在运行时设置和持久化mandatory_roles
,,请使用以下语句:
SET PERSIST mandatory_roles = 'role1,role2@localhost,r3@%.example.com';
SET PERSIST
为正在运行的MySQL实例设置值。它还保存该值,使其保留到后续服务器重新启动时。若要更改正在运行的MySQL实例的值,而不将其保留到后续重启中,请使用GLOBAL
关键字而不是PERSIST
。
设置mandatory_roles
需要ROLE_ADMIN
权限,以及设置全局系统变量所需要的SYSTEM_VARIABLES_ADMIN
权限。
强制角色与显式授予的角色一样,在激活之前不会生效。在登录时,如果activate_all_roles_on_login
系统变量是启用的,则会对所有被授予的角色进行角色激活,或者对其他设置为默认角色的角色进行角色激活。在运行时,SET ROLE
激活角色。
以mandatory_roles
命名的角色不能通过REVOKE
撤销,也不能通过DROP ROLE
或DROP USER
删除。
若要防止在默认情况下将会话设为系统会话,具有SYSTEM_USER
权限的角色不能在mandatory_roles
系统变量的值中列出:
-
如果在启动时为
mandatory_roles
分配了具有SYSTEM_USER
权限的角色,则服务器将一条消息写入错误日志并退出。 -
如果在运行时为
mandatory_roles
分配了具有SYSTEM_USER
权限的角色,则会发生错误并且mandatory_roles
值保持不变。
如果在mandatory_roles
值中出现的角色名在mysql.user
系统表中不存在,该角色不会授权给用户。当服务器尝试为用户激活角色时,它不会将不存在的角色视为强制性角色并将警告写入错误日志。如果该角色稍后创建并使其生效,则可能需要FLUSH PRIVILEGES
才能使服务器将其视为强制角色。
检查角色权限
要验证分配给帐户的权限,请使用 SHOW GRANTS
。例如:
mysql> SHOW GRANTS FOR 'dev1'@'localhost';
+-------------------------------------------------+
| Grants for dev1@localhost |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO `dev1`@`localhost` |
| GRANT `app_developer`@`%` TO `dev1`@`localhost` |
+-------------------------------------------------+
但是,这仅仅显示了每个被授予的角色,而没有将其“扩展”为角色所代表的权限。要同时显示角色权限,请添加一个USING
子句
mysql> SHOW GRANTS FOR 'dev1'@'localhost' USING 'app_developer';
+----------------------------------------------------------+
| Grants for dev1@localhost |
+----------------------------------------------------------+
| GRANT USAGE ON *.* TO `dev1`@`localhost` |
| GRANT ALL PRIVILEGES ON `app_db`.* TO `dev1`@`localhost` |
| GRANT `app_developer`@`%` TO `dev1`@`localhost` |
+----------------------------------------------------------+
类似地验证其他类型的用户:
mysql> SHOW GRANTS FOR 'read_user1'@'localhost' USING 'app_read';+--------------------------------------------------------+| Grants for read_user1@localhost |+--------------------------------------------------------+| GRANT USAGE ON *.* TO `read_user1`@`localhost` || GRANT SELECT ON `app_db`.* TO `read_user1`@`localhost` || GRANT `app_read`@`%` TO `read_user1`@`localhost` |+--------------------------------------------------------+mysql> SHOW GRANTS FOR 'rw_user1'@'localhost' USING 'app_read', 'app_write';+------------------------------------------------------------------------------+| Grants for rw_user1@localhost |+------------------------------------------------------------------------------+| GRANT USAGE ON *.* TO `rw_user1`@`localhost` || GRANT SELECT, INSERT, UPDATE, DELETE ON `app_db`.* TO `rw_user1`@`localhost` || GRANT `app_read`@`%`,`app_write`@`%` TO `rw_user1`@`localhost` |+------------------------------------------------------------------------------+
激活角色
在帐户会话中,授予用户帐户的角色可以是活跃的,也可以是不活跃的。如果一个被授予的角色在一个会话中是活跃的,那么它的权限将被应用;否则,它们就不会被应用。要确定当前会话中哪些角色是活跃的,请使用CURRENT_ROLE()
函数。
默认情况下,向帐户授予角色或在mandatory_roles
系统变量值中命名它不会自动导致该角色在帐户会话中变为活跃状态。例如,因为在前面的讨论中到目前为止还没有激活rw_user1角色,如果你以rw_user1
的身份连接服务器并调用CURRENT_ROLE()
函数,结果是NONE
(没有激活的角色):
mysql> SELECT CURRENT_ROLE();+----------------+| CURRENT_ROLE() |+----------------+| NONE |+----------------+
要指定每次用户连接到服务器并进行身份验证时应该激活哪些角色,请使用SET DEFAULT ROLE
。要为之前创建的每个帐户设置默认角色,请使用以下语句:
SET DEFAULT ROLE ALL TO 'dev1'@'localhost', 'read_user1'@'localhost', 'read_user2'@'localhost', 'rw_user1'@'localhost';
现在,如果您以 rw_user1
身份连接,则 CURRENT_ROLE()
返回值为活跃的角色:
mysql> SELECT CURRENT_ROLE();+--------------------------------+| CURRENT_ROLE() |+--------------------------------+| `app_read`@`%`,`app_write`@`%` |+--------------------------------+
要在用户连接到服务器时自动激活所有明确授予和强制的角色,请启用 activate_all_roles_on_login
系统变量。默认情况下,禁用自动角色激活。
在会话中,用户可以执行 SET ROLE
来更改活跃的角色集。例如,对于 rw_user1
:
mysql> SET ROLE NONE; SELECT CURRENT_ROLE();+----------------+| CURRENT_ROLE() |+----------------+| NONE |+----------------+mysql> SET ROLE ALL EXCEPT 'app_write'; SELECT CURRENT_ROLE();+----------------+| CURRENT_ROLE() |+----------------+| `app_read`@`%` |+----------------+mysql> SET ROLE DEFAULT; SELECT CURRENT_ROLE();+--------------------------------+| CURRENT_ROLE() |+--------------------------------+| `app_read`@`%`,`app_write`@`%` |+--------------------------------+
第一个SET ROLE
语句禁用所有角色。第二种方法使rw_user1
是只读的。第三个恢复默认角色。
撤销角色或角色权限
正如可以向帐户授予角色一样,它们也可以从帐户中撤销:
REVOKE role FROM user;
在mandatory_roles
系统变量值中命名的角色不能被撤销。
还可以对角色应用REVOKE
来修改授予它的权限。这不仅影响角色本身,还影响授予该角色的任何帐户。假设您想暂时将所有应用程序用户设为只读。为此,请使用REVOKE
从app_write
角色中撤消修改权限:
REVOKE INSERT, UPDATE, DELETE ON app_db.* FROM 'app_write';
删除角色
删除角色将会从授予该角色的每个帐户中撤销该角色。
在mandatory_roles
系统变量值中命名的角色不能被删除。
最后
以上就是勤恳薯片为你收集整理的MySQL8安全指南之账号控制与账户管理:使用角色使用角色的全部内容,希望文章能够帮你解决MySQL8安全指南之账号控制与账户管理:使用角色使用角色所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复