创建账户
添加帐户,分配特权和删除帐户
要管理MySQL帐户,请使用用于此目的的SQL语句:
CREATE USER
并DROP USER
创建和删除帐户。GRANT
并向REVOKE
帐户分配特权和从帐户撤消特权。SHOW GRANTS
显示帐户权限分配。
帐户管理语句使服务器对基础授权表进行适当的修改,这在“授权表”中进行了讨论。
注意不建议使用,,或等语句直接修改授权表
INSERT
,风险自负。服务器可以随意忽略由于此类修改而导致格式错误的行。UPDATE
DELETE
对于修改授权表的任何操作,服务器都会检查该表是否具有预期的结构,如果没有,则会产生错误。要将表更新为预期的结构,请执行MySQL升级过程。请参见“升级MySQL”。
创建帐户的另一种方法是使用GUI工具MySQL Workbench。另外,一些第三方程序提供了MySQL帐户管理功能。phpMyAdmin
是这样的程序之一。
本节讨论以下主题:
- 创建帐户和授予特权
- 检查帐户特权和属性
- 撤销帐户特权
- 删除帐户
有关此处讨论的对帐单的其他信息,请参见“账户权限控制”。
创建帐户和授予特权
以下示例显示了如何使用mysql客户端程序设置新帐户。这些示例假定MySQL root
帐户具有该CREATE USER
特权以及它授予其他帐户的所有特权。
在命令行上,以MySQL root
用户身份连接到服务器,并在密码提示下提供适当的密码:
shell>mysql -u root -p Enter password: (enter root password here)
连接到服务器后,您可以添加新帐户。以下示例使用CREATE USER
nd GRANT
语句设置四个帐户(在此处看到,用适当的密码替换):'password'
CREATE USER 'finley'@'localhost'IDENTIFIED BY 'password';GRANT ALL ON *.*TO 'finley'@'localhost'WITH GRANT OPTION ;CREATE USER 'finley'@'%.example.com'IDENTIFIED BY 'password';GRANT ALL ON *.*TO 'finley'@'%.example.com'WITH GRANT OPTION ;CREATE USER 'admin'@'localhost'IDENTIFIED BY 'password';GRANT RELOAD ,PROCESS ON *.*TO 'admin'@'localhost';CREATE USER 'dummy'@'localhost';
这些语句创建的帐户具有以下属性:
两个帐户的用户名为
finley
。两者都是具有执行任何操作的完整全局特权的超级用户帐户。'finley'@'localhost'
仅当从本地主机连接时才能使用该帐户。该'finley'@'%.example.com'
帐户'%'
在主机部分使用通配符,因此可用于从example.com
域中的任何主机进行连接。'finley'@'localhost'
如果存在的匿名用户帐户,则该帐户是必需的localhost
。如果没有该'finley'@'localhost'
帐户,finley
则从本地主机进行连接时,该匿名用户帐户将具有优先权,finley
并被视为匿名用户。原因是匿名用户帐户Host
比该'finley'@'%'
帐户具有更具体的列值,因此在user
表排序顺序中排在较早的位置。(有关user
表排序的信息,)- 该
'admin'@'localhost'
帐户只能用于通过dmin
本地主机连接。它被授予全局RELOAD
和PROCESS
管理特权。这些特权使dmin
用户能够执行mysqladmin reload,mysqladmin refresh和mysqladmin flush-xxx
命令以及mysqladmin processlist。没有访问任何数据库的特权。您可以使用GRANT
语句添加此类特权。 - 该
'dummy'@'localhost'
帐户没有密码(不安全,不建议使用)。该帐户只能用于从本地主机进行连接。不授予特权。假定您将使用GRANT
语句向该帐户授予特定特权。
前面的示例在全局级别授予特权。下一个示例创建三个帐户,并授予其较低级别的访问权限;即特定数据库或数据库中的对象。每个帐户的用户名均为custom
,但主机名部分有所不同:
CREATE USER 'custom'@'localhost'IDENTIFIED BY 'password';GRANT ALL ON bankaccount.*TO 'custom'@'localhost';CREATE USER 'custom'@'host47.example.com'IDENTIFIED BY 'password';GRANT SELECT ,INSERT ,UPDATE ,DELETE ,CREATE ,DROP ON expenses.*TO 'custom'@'host47.example.com';CREATE USER 'custom'@'%.example.com'IDENTIFIED BY 'password';GRANT SELECT ,INSERT ,UPDATE ,DELETE ,CREATE ,DROP ON customer. ddressesTO 'custom'@'%.example.com';
这三个帐户可以如下使用:
- 该
'custom'@'localhost'
帐户具有访问bankaccount
数据库的所有数据库级特权。该帐户只能用于从本地主机连接到服务器。 - 该
'custom'@'host47.example.com'
帐户具有访问expenses
数据库的特定数据库级别特权。该帐户只能用于从主机连接到服务器host47.example.com
。 - 该
'custom'@'%.example.com'
帐户具有特定的表级特权,可以从域中的任何主机访问数据库中的ddresses
表。由于在帐户名称的主机部分使用了通配符,因此该帐户可用于从域中的所有计算机连接到服务器。customer
example.com
%
检查帐户特权和属性
要参见帐户的特权,请使用SHOW GRANTS
:
mysql>SHOW GRANTS FOR 'admin'@'localhost'; +----------------------------------------------------- + | Grants for admin@localhost | +----------------------------------------------------- + | GRANT RELOAD, PROCESS ON *.* TO 'admin'@'localhost' | +----------------------------------------------------- +
要参见帐户的非特权属性,请使用SHOW CREATE USER
:
mysql>SET print_identified_with_as_hex =ON ; mysql>SHOW CREATE USER 'admin'@'localhost'\G *************************** 1. row *************************** CREATE USER for admin@localhost : CREATE USER 'admin'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS 0x24412430303524301D0E17054E2241362B1419313C3E44326F294133734B30792F436E77764270373039612E32445250786D43594F45354532324B6169794F47457852796E32 REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT
启用print_identified_with_as_hex
系统变量(自MySQL 8.0.17起可用)会导致SHOW CREATE USER
将包含不可打印字符的哈希值显示为十六进制字符串而不是常规字符串文字。
撤销帐户特权
要撤消帐户特权,请使用以下REVOKE
语句。可以在不同级别撤销特权,就像可以在不同级别授予特权一样。
撤销全局特权:
REVOKE ALL ON *.*FROM 'finley'@'%.example.com';REVOKE RELOAD ON *.*FROM 'admin'@'localhost';
撤消数据库级特权:
REVOKE CREATE ,DROP ON expenses.*FROM 'custom'@'host47.example.com';
撤消表级特权:
REVOKE INSERT ,UPDATE ,DELETE ON customer. ddressesFROM 'custom'@'%.example.com';
要检查特权撤销的效果,请使用SHOW GRANTS
:
mysql>SHOW GRANTS FOR 'admin'@'localhost'; +--------------------------------------------- + | Grants for admin@localhost | +--------------------------------------------- + | GRANT PROCESS ON *.* TO 'admin'@'localhost' | +--------------------------------------------- +
删除帐户
要删除帐户,请使用以下DROP USER
语句。例如,删除一些先前创建的帐户:
DROP USER 'finley'@'localhost';DROP USER 'finley'@'%.example.com';DROP USER 'admin'@'localhost';DROP USER 'dummy'@'localhost';
预留帐户
MySQL安装过程的一部分是数据目录初始化(请参见“初始化数据目录”)。在数据目录初始化期间,MySQL创建应被视为保留的用户帐户:
'root'@'localhost
:用于管理目的。该帐户具有所有特权,是系统帐户,并且可以执行任何操作。严格来说,此帐户名不是保留的,在某种意义上,某些安装会将
root
帐户重命名为其他名称,以避免暴露具有知名名的高特权帐户。'mysql.sys'@'localhost'
:作为DEFINER
对sys
架构对象。使用该mysql.sys
帐户可以避免在DBA重命名或删除该root
帐户时发生的问题。此帐户已锁定,因此不能用于客户端连接。'mysql.session'@'localhost'
:由插件内部使用以访问服务器。此帐户已锁定,因此不能用于客户端连接。该帐户是系统帐户。'mysql.infoschema'@'localhost'
:作为DEFINER
对INFORMATION_SCHEMA
意见。使用该mysql.infoschem
帐户避免了DBA重命名或删除根帐户时发生的问题。此帐户已锁定,因此不能用于客户端连接。
使用角色
MySQL角色是特权的命名集合。像用户帐户一样,角色可以拥有授予和撤销的特权。
可以授予用户帐户角色,这些角色将与每个角色关联的特权授予该帐户。这样就可以将特权集分配给帐户,并为授予个人特权提供了一种方便的替代方法,既可以概念化所需的特权分配,又可以实现它们。
以下列表总结了MySQL提供的角色管理功能:
CREATE ROLE
并DROP ROLE
创建和删除角色。GRANT
并REVOKE
分配特权以撤消用户帐户和角色的特权。SHOW GRANTS
显示用户帐户和角色的特权和角色分配。SET DEFAULT ROLE
指定默认情况下哪些帐户角色处于活动状态。SET ROLE
更改当前会话中的活动角色。- 该
CURRENT_ROLE()
功能显示当前会话中的活动角色。 - 该
mandatory_roles
和ctivate_all_roles_on_login
系统变量允许定义强制性角色和授予的角色的自动激活,当用户登录到服务器。
有关单个角色操作语句的描述(包括使用它们所需的特权),请参见“账户权限控制”。以下讨论提供了角色用法的示例。除非另有说明,否则此处显示的SQL语句应使用具有足够管理特权的MySQL帐户(例如该root
帐户)执行。
- 创建角色并授予他们特权
- 定义强制性角色
- 检查角色特权
- 激活角色
- 撤销角色或角色特权
- 放弃角色
- 用户和角色互换性
创建角色并授予他们特权
考虑这种情况:
- 应用程序使用名为的数据库
pp_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
与刚才所示相同的形式的语句,但这需要枚举每个用户的特权。而是,使用GRANT
允许授予角色而不是特权的替代语法:
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';
该帐户的GRANT
语句rw_user1
授予读取和写入角色,这些角色结合在一起以提供所需的读取和写入权限。
该GRANT
语法授予角色从语法的账户为不同权限的授予:有一个ON
分配特权条款,而没有ON
到指定角色条款。因为语法是不同的,所以您不能在同一条语句中混合分配特权和角色。(允许为帐户分配特权和角色,但是您必须使用单独的GRANT
语句,每个语句的语法都适合要授予的语法。)从MySQL 8.0.16开始,不能将角色授予匿名用户。
创建角色时,该角色将被锁定,没有密码并被分配默认身份验证插件。(ALTER USER
具有全局CREATE USER
特权的用户可以在以后使用该语句更改这些角色属性。)
锁定后,角色不能用于向服务器进行身份验证。如果解锁,则可以使用角色进行身份验证。这是因为角色和用户都是授权标识符,它们有很多共同点,而很少区分它们。另请参阅用户和角色互换性。
定义强制性角色
通过将角色命名为mandatory_roles
系统变量的值,可以将其指定为强制角色。服务器将强制角色视为授予所有用户的角色,因此无需将其明确授予任何帐户。
要在服务器启动时指定强制角色,请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
。请参见“变量分配的SET语法”。
除了设置全局系统变量通常需要的或特权外,设置还mandatory_roles
需要ROLE_ADMIN
特权。SYSTEM_VARIABLES_ADMIN
SUPER
强制角色(如显式授予的角色)在激活之前不会生效(请参阅激活角色)。在登录时,如果 ctivate_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
不存在名为in的角色,则不会mysql.user
将该角色授予用户。当服务器尝试为用户激活角色时,它不会将不存在的角色视为必需角色,并且会向错误日志写入警告。如果角色是在以后创建的,因此变得有效,则FLUSH PRIVILEGES
可能需要使服务器将其视为必需角色。
SHOW GRANTS
根据“ SHOW GRANTS语句”中所述的规则显示强制性角色。
检查角色特权
要验证分配给帐户的特权,请使用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` | +------------------------------------------------------------------------------ +
SHOW GRANTS
根据“ SHOW GRANTS语句”中所述的规则显示强制性角色。
激活角色
在帐户会话中,授予用户帐户的角色可以处于活动状态,也可以处于非活动状态。如果授予的角色在会话中处于活动状态,则其特权适用;否则,他们不会。要确定当前会话中哪些角色处于活动状态,请使用该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`@`%` | +-------------------------------- +
要在用户连接到服务器时自动激活所有明确授予和强制角色,请启用 ctivate_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
有效地只读。第三个恢复默认角色。
存储程序和视图对象的有效用户受DEFINER
和SQL SECURITY
属性的约束,该属性确定执行是在调用者上下文还是在定义者上下文中发生(请参见“存储对象访问控制”):
- 在调用者上下文中执行的存储的程序和视图对象以当前会话中处于活动状态的角色执行。
- 在定义程序上下文中执行的存储程序和视图对象将使用在其
DEFINER
属性中命名的用户的默认角色执行。如果ctivate_all_roles_on_login
启用,则此类对象将以授予DEFINER
用户的所有角色(包括强制角色)执行。对于存储程序,如果执行角色的角色不同于默认角色,则应执行程序主体SET ROLE
以激活所需的角色。
撤销角色或角色特权
就像可以将角色授予帐户一样,也可以从帐户中撤销角色:
REVOKE roleFROM user;
mandatory_roles
无法撤销在系统变量值中命名的角色。
REVOKE
也可以应用于角色以修改授予它的特权。这不仅影响角色本身,还影响授予该角色的任何帐户。假设您要暂时使所有应用程序用户只读。为此,请使用REVOKE
撤销 pp_write
角色的修改权限:
REVOKE INSERT ,UPDATE ,DELETE ON app_db.*FROM 'app_write';
碰巧的是,这使角色完全没有特权,就像使用可以看到的那样SHOW GRANTS
(这表明该语句可以与角色一起使用,而不仅仅是用户):
mysql>SHOW GRANTS FOR 'app_write'; +--------------------------------------- + | Grants for app_write@% | +--------------------------------------- + | GRANT USAGE ON *.* TO `app_write`@`%` | +--------------------------------------- +
因为从角色中撤销特权会影响谁被分配了修改角色的任何用户的权限,rw_user1
现在已经没有表修改权限(INSERT
,UPDATE
,和DELETE
不再存在):
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 ON `app_db`.* TO `rw_user1`@`localhost` | | GRANT `app_read`@`%`,`app_write`@`%` TO `rw_user1`@`localhost` | +---------------------------------------------------------------- +
实际上,rw_user1
读/写用户已成为只读用户。对于其他被授予该 pp_write
角色的帐户,也会发生这种情况,这说明使用角色如何使不必修改单个帐户的特权。
要恢复角色的修改特权,只需重新授予它们:
GRANT INSERT ,UPDATE ,DELETE ON app_db.*TO 'app_write';
现在,rw_user1
再次具有修改权限,其他所有授予该 pp_write
角色的帐户也是如此。
放弃角色
要删除角色,请使用DROP ROLE
:
DROP ROLE 'app_read', 'app_write';
删除角色会从授予该角色的每个帐户中撤消该角色。
mandatory_roles
无法删除在系统变量值中命名的角色。
用户和角色互换性
如前所述SHOW GRANTS
,它显示了用户帐户或角色的授予,帐户和角色可以互换使用。
角色和用户之间的区别是CREATE ROLE
创建默认情况下锁定CREATE USER
的授权标识符,而创建默认情况下解锁的授权标识符。但是,区别并不是一成不变的,因为具有适当特权的用户可以在角色或用户创建后锁定或解锁。
如果数据库管理员偏好特定授权标识符必须是角色,则可以使用名称方案来传达此意图。例如,您可以r_
为打算成为角色的所有授权标识符使用前缀,而不能使用其他任何标识符。
角色和用户之间的另一个区别在于可用于管理角色和用户的特权:
- 在
CREATE ROLE
和DROP ROLE
特权只允许使用的CREATE ROLE
,并DROP ROLE
分别发言。 - 该
CREATE USER
权限允许使用的ALTER USER
,CREATE ROLE
,CREATE USER
,DROP ROLE
,DROP USER
,RENAME USER
,和REVOKE ALL PRIVILEGES
语句。
因此,CREATE ROLE
和DROP ROLE
特权不如强大CREATE 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';
在每种情况下,结果是向被授予者对象授予与被授予对象相关联的特权。执行这些语句,每个后u2
和r2
已授予的权限从用户(u1
)和角色(r1
):
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`@`%` | +------------------------------------- +
上面的示例仅是说明性的,但是用户帐户和角色的可互换性具有实际应用,例如在以下情况下:假设旧版应用程序开发项目在MySQL角色出现之前就开始了,因此与该项目关联的所有用户帐户都是直接授予特权(而不是由于被授予角色而授予特权)。这些帐户之一是最初被授予特权的开发者帐户,如下所示:
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';效果是将原始开发者帐户特权分配给新帐户。