GRANT
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
TO user_or_role [, user_or_role] ...
[WITH GRANT OPTION]
[AS user
[WITH ROLE
DEFAULT
| NONE
| ALL
| ALL EXCEPT role [, role ] ...
| role [, role ] ...
]
]
}
GRANT PROXY ON user_or_role
TO user_or_role [, user_or_role] ...
[WITH GRANT OPTION]
GRANT role [, role] ...
TO user_or_role [, user_or_role] ...
[WITH ADMIN OPTION]
object_type: {
TABLE
| FUNCTION
| PROCEDURE
}
priv_level: {
*
| *.*
| db_name.*
| db_name.tbl_name
| tbl_name
| db_name.routine_name
}
user_or_role: {
user (see Section 8.2.4, “Specifying Account Names”)
| role (see Section 8.2.5, “Specifying Role Names”)
}
The GRANT
语句将权限和角色分配给 MySQL 用户帐户和角色。The GRANT
语句有几个方面,在以下主题中进行描述
The GRANT
语句允许系统管理员授予权限和角色,这些权限和角色可以授予用户帐户和角色。这些语法限制适用
有关角色的更多信息,请参见 第 8.2.10 节,“使用角色”。
要使用 GRANT
授予权限,您必须拥有 GRANT OPTION
权限,并且您必须拥有要授予的权限。(或者,如果您拥有 mysql
系统架构中授权表的 UPDATE
权限,您可以将任何权限授予任何账户。)当 read_only
系统变量启用时,GRANT
还需要 CONNECTION_ADMIN
权限(或已弃用的 SUPER
权限)。
GRANT
对于所有命名的用户和角色都成功,或者回滚并且没有任何效果,如果发生任何错误。该语句仅在对所有命名用户和角色都成功的情况下才写入二进制日志。
REVOKE
语句与 GRANT
相关,它使管理员能够删除账户权限。请参见 第 15.7.1.8 节,“REVOKE 语句”。
每个账户名都使用 第 8.2.4 节,“指定账户名” 中描述的格式。每个角色名都使用 第 8.2.5 节,“指定角色名” 中描述的格式。例如
GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
GRANT SELECT ON world.* TO 'role3';
如果省略账户名或角色名的主机名部分,则默认为 '%'
。
通常,数据库管理员首先使用 CREATE USER
创建账户并定义其非权限特征,例如其密码、是否使用安全连接以及对服务器资源访问的限制,然后使用 GRANT
定义其权限。可以使用 ALTER USER
更改现有账户的非权限特征。例如
CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';
ALTER USER 'jeffrey'@'localhost' WITH MAX_QUERIES_PER_HOUR 90;
在 mysql 程序中,当 GRANT
成功执行时,它会返回 Query OK, 0 rows affected
。要确定操作产生的权限,请使用 SHOW GRANTS
。请参见 第 15.7.7.22 节,“SHOW GRANTS 语句”。
在某些情况下,GRANT
可能会记录在服务器日志中或在客户端的历史记录文件中(例如 ~/.mysql_history
)中,这意味着任何拥有读取该信息权限的人都可能读取明文密码。有关服务器日志中发生此情况的条件以及如何控制它的信息,请参见 第 8.1.2.3 节,“密码和日志记录”。有关客户端日志记录的类似信息,请参见 第 6.5.1.3 节,“mysql 客户端日志记录”。
GRANT
支持最长 255 个字符的主机名。用户名最多可以有 32 个字符。数据库、表、列和例程名称最多可以有 64 个字符。
不要尝试通过更改 mysql.user
系统表来更改用户名允许的长度。这样做会导致不可预测的行为,甚至可能导致用户无法登录到 MySQL 服务器。 绝不以任何方式更改 mysql
系统架构中表的结构,除非通过 第 3 章,升级 MySQL 中描述的过程。
GRANT
语句中的几个对象需要引用,尽管在许多情况下引用是可选的:账户、角色、数据库、表、列和例程名称。例如,如果账户名中的 user_name
或 host_name
值作为未引用的标识符合法,则无需引用它。但是,需要使用引号来指定包含特殊字符(例如 -
)的 user_name
字符串,或者包含特殊字符或通配符(例如 %
)(例如 'test-user'@'%.com'
)的 host_name
字符串。分别引用用户名和主机名。
要指定带引号的值
将数据库、表、列和例程名称引用为标识符。
将用户名和主机名引用为标识符或字符串。
将密码引用为字符串。
有关字符串引用和标识符引用准则,请参见 第 11.1.1 节,“字符串文字” 和 第 11.2 节,“架构对象名称”。
在接下来的几段中描述的通配符 %
和 _
的使用已过时,因此可能会在 MySQL 的未来版本中删除。
在指定 GRANT
语句中数据库名称时,允许使用 _
和 %
通配符,这些语句在数据库级别授予权限 (GRANT ... ON
)。这意味着,例如,要将 db_name
.*_
字符用作数据库名称的一部分,请在 GRANT
语句中使用 \
转义字符指定为 \_
,以防止用户能够访问匹配通配符模式的更多数据库(例如,GRANT ... ON `foo\_bar`.* TO ...
)。
发出包含通配符的多个 GRANT
语句可能不会对 DML 语句产生预期的效果;在解析涉及通配符的授权时,MySQL 仅考虑第一个匹配的授权。换句话说,如果用户有两个使用通配符且匹配相同数据库的数据库级授权,则首先创建的授权将应用。考虑使用此处显示的语句创建的数据库 db
和表 t
mysql> CREATE DATABASE db;
Query OK, 1 row affected (0.01 sec)
mysql> CREATE TABLE db.t (c INT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO db.t VALUES ROW(1);
Query OK, 1 row affected (0.00 sec)
接下来(假设当前账户是 MySQL root
账户或具有必要权限的另一个账户),我们创建一个用户 u
,然后发出两个包含通配符的 GRANT
语句,如下所示
mysql> CREATE USER u;
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT SELECT ON `d_`.* TO u;
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT INSERT ON `d%`.* TO u;
Query OK, 0 rows affected (0.00 sec)
mysql> EXIT
Bye
如果我们结束会话,然后使用 mysql 客户端再次登录,这次作为 u,我们会看到该账户仅拥有第一个匹配授权提供的权限,而没有第二个授权提供的权限
$> mysql -uu -hlocalhost
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 9.1.0-tr Source distribution
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input
statement.
mysql> TABLE db.t;
+------+
| c |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> INSERT INTO db.t VALUES ROW(2);
ERROR 1142 (42000): INSERT command denied to user 'u'@'localhost' for table 't'
在权限分配中,MySQL 在以下情况下将数据库名称中未转义的 _
和 %
SQL 通配符解释为文字字符
当数据库名称不用于在数据库级别授予权限,而是用作限定符来授予对其他对象(如表或例程)的权限时(例如,
GRANT ... ON
)。db_name
.tbl_name
启用
partial_revokes
会导致 MySQL 将数据库名称中未转义的_
和%
通配符解释为文字字符,就像它们已转义为\_
和\%
一样。由于这会改变 MySQL 解释权限的方式,因此建议在partial_revokes
可能启用的安装中避免在权限分配中使用未转义的通配符。有关更多信息,请参见 第 8.2.12 节,“使用部分撤销限制权限”。
GRANT
语句中的 user
值表示该语句适用的 MySQL 账户。为了适应从任意主机授予用户权限,MySQL 支持以 '
的形式指定 user_name
'@'host_name
'user
值。
您可以在主机名中指定通配符。例如,'
应用于 user_name
'@'%.example.com'example.com
域中任何主机的 user_name
,而 '
应用于 user_name
'@'198.51.100.%'198.51.100
类 C 子网中任何主机的 user_name
。
简单形式 '
是 user_name
''
的同义词。user_name
'@'%'
MySQL 会自动将授予 '
的所有权限也分配给 username
'@'%''
账户。此行为已过时,可能会在 MySQL 的未来版本中删除。username
'@'localhost'
MySQL 不支持用户名中的通配符。 要引用匿名用户,请使用 GRANT
语句指定具有空用户名的账户
GRANT ALL ON test.* TO ''@'localhost' ...;
在这种情况下,任何从本地主机连接并具有匿名用户正确密码的用户都将被允许访问,并拥有与匿名用户账户关联的权限。
有关账户名中用户名和主机名值的更多信息,请参见 第 8.2.4 节,“指定账户名”。
如果您允许本地匿名用户连接到 MySQL 服务器,您还应该将权限授予所有本地用户,作为 '
。否则,当命名用户尝试从本地计算机登录到 MySQL 服务器时,将使用 user_name
'@'localhost'mysql.user
系统表中 localhost
的匿名用户账户。有关详细信息,请参见 第 8.2.6 节,“访问控制,阶段 1:连接验证”。
要确定此问题是否适用于您,请执行以下查询,该查询列出所有匿名用户
SELECT Host, User FROM mysql.user WHERE User='';
要避免刚刚描述的问题,请使用以下语句删除本地匿名用户账户
DROP USER ''@'localhost';
以下表格总结了可为 GRANT
和 REVOKE
语句指定的允许的静态和动态 priv_type
权限类型,以及可以授予每个权限的级别。有关每个权限的更多信息,请参见 第 8.2.2 节,“MySQL 提供的权限”。有关静态权限和动态权限之间差异的信息,请参见 静态与动态权限。
表 15.11 GRANT 和 REVOKE 允许的静态权限
权限 | 含义和可授予级别 |
---|---|
ALL [PRIVILEGES] |
授予指定访问级别下的所有权限,但 GRANT OPTION 和 PROXY 除外。 |
ALTER |
启用使用 ALTER TABLE 。级别:全局、数据库、表。 |
ALTER ROUTINE |
允许更改或删除存储例程。级别:全局、数据库、例程。 |
CREATE |
启用数据库和表创建。级别:全局、数据库、表。 |
CREATE ROLE |
启用角色创建。级别:全局。 |
CREATE ROUTINE |
启用存储例程创建。级别:全局、数据库。 |
CREATE TABLESPACE |
允许创建、更改或删除表空间和日志文件组。级别:全局。 |
CREATE TEMPORARY TABLES |
启用使用 CREATE TEMPORARY TABLE 。级别:全局、数据库。 |
CREATE USER |
启用使用 CREATE USER 、DROP USER 、RENAME USER 和 REVOKE ALL PRIVILEGES 。级别:全局。 |
CREATE VIEW |
允许创建或更改视图。级别:全局、数据库、表。 |
DELETE |
启用使用 DELETE 。级别:全局、数据库、表。 |
DROP |
允许删除数据库、表和视图。级别:全局、数据库、表。 |
DROP ROLE |
允许删除角色。级别:全局。 |
EVENT |
启用使用事件调度程序的事件。级别:全局、数据库。 |
EXECUTE |
允许用户执行存储例程。级别:全局、数据库、例程。 |
FILE |
允许用户使服务器读取或写入文件。级别:全局。 |
FLUSH_PRIVILEGES |
允许用户发出 FLUSH PRIVILEGES 语句。级别:全局。 |
GRANT OPTION |
允许将权限授予或从其他帐户中删除。级别:全局、数据库、表、例程、代理。 |
INDEX |
允许创建或删除索引。级别:全局、数据库、表。 |
INSERT |
启用使用 INSERT 。级别:全局、数据库、表、列。 |
LOCK TABLES |
允许在您具有 SELECT 权限的表上使用 LOCK TABLES 。级别:全局、数据库。 |
OPTIMIZE_LOCAL_TABLE |
启用使用 OPTIMIZE LOCAL TABLE 或 OPTIMIZE NO_WRITE_TO_BINLOG TABLE 。级别:全局、数据库、表。 |
PROCESS |
允许用户使用 SHOW PROCESSLIST 查看所有进程。级别:全局。 |
PROXY |
允许用户代理。级别:从用户到用户。 |
REFERENCES |
允许创建外键。级别:全局、数据库、表、列。 |
RELOAD |
启用使用 FLUSH 操作。级别:全局。 |
REPLICATION CLIENT |
允许用户询问源服务器或副本服务器的位置。级别:全局。 |
REPLICATION SLAVE |
允许副本从源读取二进制日志事件。级别:全局。 |
SELECT |
启用使用 SELECT 。级别:全局、数据库、表、列。 |
SHOW DATABASES |
启用 SHOW DATABASES 以显示所有数据库。级别:全局。 |
SHOW VIEW |
启用使用 SHOW CREATE VIEW 。级别:全局、数据库、表。 |
SHUTDOWN |
启用使用 mysqladmin shutdown。级别:全局。 |
SUPER |
启用使用其他管理操作,例如 CHANGE REPLICATION SOURCE TO 、KILL 、PURGE BINARY LOGS 、SET GLOBAL 和 mysqladmin debug 命令。级别:全局。 |
TRIGGER |
启用触发器操作。级别:全局、数据库、表。 |
UPDATE |
启用使用 UPDATE 。级别:全局、数据库、表、列。 |
USAGE |
是 “无权限” 的同义词 |
表 15.12 GRANT 和 REVOKE 允许的动态权限
权限 | 含义和可授予级别 |
---|---|
APPLICATION_PASSWORD_ADMIN |
启用双重密码管理。级别:全局。 |
AUDIT_ABORT_EXEMPT |
允许被审计日志过滤器阻止的查询。级别:全局。 |
AUDIT_ADMIN |
启用审计日志配置。级别:全局。 |
AUTHENTICATION_POLICY_ADMIN |
启用身份验证策略管理。级别:全局。 |
BACKUP_ADMIN |
启用备份管理。级别:全局。 |
BINLOG_ADMIN |
启用二进制日志控制。级别:全局。 |
BINLOG_ENCRYPTION_ADMIN |
启用二进制日志加密的激活和停用。级别:全局。 |
CLONE_ADMIN |
启用克隆管理。级别:全局。 |
CONNECTION_ADMIN |
启用连接限制/限制控制。级别:全局。 |
ENCRYPTION_KEY_ADMIN |
启用 InnoDB 密钥轮换。级别:全局。 |
FIREWALL_ADMIN |
启用防火墙规则管理,任何用户。级别:全局。 |
FIREWALL_EXEMPT |
免除用户防火墙限制。级别:全局。 |
FIREWALL_USER |
启用防火墙规则管理,自身。级别:全局。 |
FLUSH_OPTIMIZER_COSTS |
启用优化器成本重新加载。级别:全局。 |
FLUSH_STATUS |
启用状态指示器刷新。级别:全局。 |
FLUSH_TABLES |
启用表刷新。级别:全局。 |
FLUSH_USER_RESOURCES |
启用用户资源刷新。级别:全局。 |
GROUP_REPLICATION_ADMIN |
启用组复制控制。级别:全局。 |
INNODB_REDO_LOG_ARCHIVE |
启用重做日志存档管理。级别:全局。 |
INNODB_REDO_LOG_ENABLE |
启用或禁用重做日志记录。级别:全局。 |
NDB_STORED_USER |
启用在 SQL 节点(NDB 集群)之间共享用户或角色。级别:全局。 |
PASSWORDLESS_USER_ADMIN |
启用无密码用户帐户管理。级别:全局。 |
PERSIST_RO_VARIABLES_ADMIN |
启用持久化只读系统变量。级别:全局。 |
REPLICATION_APPLIER |
充当复制通道的 PRIVILEGE_CHECKS_USER 。级别:全局。 |
REPLICATION_SLAVE_ADMIN |
启用常规复制控制。级别:全局。 |
RESOURCE_GROUP_ADMIN |
启用资源组管理。级别:全局。 |
RESOURCE_GROUP_USER |
启用资源组管理。级别:全局。 |
ROLE_ADMIN |
启用角色授予或撤销,使用 WITH ADMIN OPTION 。级别:全局。 |
SESSION_VARIABLES_ADMIN |
启用设置受限制的会话系统变量。级别:全局。 |
SHOW_ROUTINE |
启用访问存储例程定义。级别:全局。 |
SKIP_QUERY_REWRITE |
不重写此用户执行的查询。级别:全局。 |
SYSTEM_USER |
将帐户指定为系统帐户。级别:全局。 |
SYSTEM_VARIABLES_ADMIN |
启用修改或持久化全局系统变量。级别:全局。 |
TABLE_ENCRYPTION_ADMIN |
启用覆盖默认加密设置。级别:全局。 |
TELEMETRY_LOG_ADMIN |
启用 AWS 上 HeatWave 的遥测日志配置。级别:全局。 |
TP_CONNECTION_ADMIN |
启用线程池连接管理。级别:全局。 |
VERSION_TOKEN_ADMIN |
启用使用版本令牌函数。级别:全局。 |
XA_RECOVER_ADMIN |
启用 XA RECOVER 执行。级别:全局。 |
触发器与表相关联。要创建或删除触发器,您必须对表具有 TRIGGER
权限,而不是对触发器。
在 GRANT
语句中,ALL [PRIVILEGES]
或 PROXY
权限必须单独命名,不能与其他权限一起指定。 ALL [PRIVILEGES]
代表在要授予权限的级别上可用的所有权限,但 GRANT OPTION
和 PROXY
权限除外。
MySQL 帐户信息存储在 mysql
系统模式的表中。有关更多详细信息,请参阅 第 8.2 节,“访问控制和帐户管理”,其中详细讨论了 mysql
系统模式和访问控制系统。
如果授予表包含包含混合大小写数据库或表名的权限行,并且 lower_case_table_names
系统变量设置为非零值,则 REVOKE
无法用于撤销这些权限。在这种情况下,必须直接操作授予表。(GRANT
在 lower_case_table_names
设置时不会创建这样的行,但这样的行可能是在设置该变量之前创建的。 lower_case_table_names
设置只能在服务器启动时配置。)
根据用于 ON
子句的语法,权限可以在多个级别授予。对于 REVOKE
,相同的 ON
语法指定要删除哪些权限。
对于全局、数据库、表和例程级别,GRANT ALL
仅分配在您授予权限的级别上存在的权限。例如,GRANT ALL ON
是数据库级语句,因此它不会授予任何全局专用权限,例如 db_name
.*FILE
。授予 ALL
不会分配 GRANT OPTION
或 PROXY
权限。
如果存在,则当以下对象是表、存储函数或存储过程时,object_type
子句应指定为 TABLE
、FUNCTION
或 PROCEDURE
。
用户对数据库、表、列或例程拥有的权限是每个权限级别的帐户权限(包括全局级别)的逻辑 OR
形成的。无法通过在较低级别上没有该权限来拒绝在较高级别上授予的权限。例如,此语句在全局范围内授予 SELECT
和 INSERT
权限
GRANT SELECT, INSERT ON *.* TO u1;
全局授予的权限适用于所有数据库、表和列,即使未在任何这些较低级别授予。
如果 partial_revokes
系统变量已启用,则可以通过撤销特定数据库的全局级别授予的权限来显式拒绝该权限。
GRANT SELECT, INSERT, UPDATE ON *.* TO u1;
REVOKE INSERT, UPDATE ON db1.* FROM u1;
前面语句的结果是 SELECT
全局应用于所有表,而 INSERT
和 UPDATE
全局应用,但不适用于 db1
中的表。对 db1
的帐户访问权限为只读。
权限检查过程的详细信息在 第 8.2.7 节,“访问控制,阶段 2:请求验证” 中介绍。
如果您对任何用户使用表、列或例程权限,服务器将检查所有用户的表、列和例程权限,这会稍微减慢 MySQL 的速度。类似地,如果您限制任何用户的查询、更新或连接数量,服务器必须监控这些值。
MySQL 使您能够对不存在的数据库或表授予权限。对于表,要授予的权限必须包括 CREATE
权限。 这种行为是设计使然,旨在使数据库管理员能够为稍后要创建的数据库或表准备用户帐户和权限。
当您删除数据库或表时,MySQL 不会自动撤销任何权限。但是,如果删除例程,将撤销为该例程授予的任何例程级别权限。
全局权限是管理性的,或者适用于给定服务器上的所有数据库。要分配全局权限,请使用 ON *.*
语法。
GRANT ALL ON *.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';
CREATE TABLESPACE
、CREATE USER
、FILE
、PROCESS
、RELOAD
、REPLICATION CLIENT
、REPLICATION SLAVE
、SHOW DATABASES
、SHUTDOWN
和 SUPER
静态权限是管理性的,只能在全局授予。
动态权限都是全局性的,只能在全局授予。
其他权限可以在全局或更具体的级别授予。
在全局级别授予 GRANT OPTION
对静态和动态权限的影响不同。
对于任何静态全局权限授予的
GRANT OPTION
适用于所有静态全局权限。对于任何动态权限授予的
GRANT OPTION
仅适用于该动态权限。
在全局级别授予 GRANT ALL
将授予所有静态全局权限和所有当前注册的动态权限。在执行 GRANT
语句后注册的动态权限不会追溯授予任何帐户。
MySQL 将全局权限存储在 mysql.user
系统表中。
数据库权限适用于给定数据库中的所有对象。要分配数据库级权限,请使用 ON
语法。db_name
.*
GRANT ALL ON mydb.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';
如果您使用 ON *
语法(而不是 ON *.*
),则权限将针对默认数据库在数据库级别分配。如果不存在默认数据库,则会发生错误。
在数据库级别可以指定 CREATE
、DROP
、EVENT
、GRANT OPTION
、LOCK TABLES
和 REFERENCES
权限。表或例程权限也可以在数据库级别指定,在这种情况下,它们适用于数据库中的所有表或例程。
MySQL 将数据库权限存储在 mysql.db
系统表中。
表权限适用于给定表中的所有列。要分配表级权限,请使用 ON
语法。db_name.tbl_name
GRANT ALL ON mydb.mytbl TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON mydb.mytbl TO 'someuser'@'somehost';
如果您指定 tbl_name
而不是 db_name.tbl_name
,则语句将应用于默认数据库中的 tbl_name
。如果不存在默认数据库,则会发生错误。
在表级别允许的 priv_type
值是 ALTER
、CREATE VIEW
、CREATE
、DELETE
、DROP
、GRANT OPTION
、INDEX
、INSERT
、REFERENCES
、SELECT
、SHOW VIEW
、TRIGGER
和 UPDATE
。
表级权限适用于基本表和视图。它们不适用于使用 CREATE TEMPORARY TABLE
创建的表,即使表名匹配。有关 TEMPORARY
表权限的信息,请参见 第 15.1.20.2 节,“CREATE TEMPORARY TABLE 语句”。
MySQL 将表权限存储在 mysql.tables_priv
系统表中。
列权限适用于给定表中的单个列。在列级别授予的每个权限后面必须是列或列,并用括号括起来。
GRANT SELECT (col1), INSERT (col1, col2) ON mydb.mytbl TO 'someuser'@'somehost';
列允许的 priv_type
值(即,当您使用 column_list
子句时)是 INSERT
、REFERENCES
、SELECT
和 UPDATE
。
MySQL 将列权限存储在 mysql.columns_priv
系统表中。
ALTER ROUTINE
、CREATE ROUTINE
、EXECUTE
和 GRANT OPTION
权限适用于存储例程(过程和函数)。它们可以在全局和数据库级别授予。除了 CREATE ROUTINE
外,这些权限可以在例程级别为各个例程授予。
GRANT CREATE ROUTINE ON mydb.* TO 'someuser'@'somehost';
GRANT EXECUTE ON PROCEDURE mydb.myproc TO 'someuser'@'somehost';
在例程级别允许的 priv_type
值是 ALTER ROUTINE
、EXECUTE
和 GRANT OPTION
。 CREATE ROUTINE
不是例程级权限,因为您必须在全局或数据库级别拥有权限才能首先在其中创建例程。
MySQL 将例程级权限存储在 mysql.procs_priv
系统表中。
PROXY
权限使一个用户能够成为另一个用户的代理。代理用户冒充或接管被代理用户的身份;也就是说,它承担被代理用户的权限。
GRANT PROXY ON 'localuser'@'localhost' TO 'externaluser'@'somehost';
当授予 PROXY
时,它必须是 GRANT
语句中命名的唯一权限,并且唯一允许的 WITH
选项是 WITH GRANT OPTION
。
代理需要代理用户通过在代理用户连接时将被代理用户的名称返回给服务器的插件进行身份验证,并且代理用户对被代理用户具有 PROXY
权限。有关详细信息和示例,请参见 第 8.2.19 节,“代理用户”。
MySQL 将代理权限存储在 mysql.proxies_priv
系统表中。
没有 ON
子句的 GRANT
语法授予角色而不是单个权限。角色是权限的命名集合;请参见 第 8.2.10 节,“使用角色”。例如
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
要授予的每个角色必须存在,以及要授予该角色的每个用户帐户或角色。角色不能授予匿名用户。
授予角色不会自动导致角色处于活动状态。有关角色激活和停用的信息,请参见 激活角色。
以下权限是授予角色所需的权限。
如果您具有
ROLE_ADMIN
权限(或已弃用的SUPER
权限),您可以向用户或角色授予或撤销任何角色。如果您使用包含
WITH ADMIN OPTION
子句的GRANT
语句授予了角色,您将能够向其他用户或角色授予该角色,或从其他用户或角色撤销该角色,只要该角色在您随后授予或撤销该角色时处于活动状态。这包括使用WITH ADMIN OPTION
本身的能力。要授予具有
SYSTEM_USER
权限的角色,您必须具有SYSTEM_USER
权限。
可以使用 GRANT
创建循环引用。例如
CREATE USER 'u1', 'u2';
CREATE ROLE 'r1', 'r2';
GRANT 'u1' TO 'u1'; -- simple loop: u1 => u1
GRANT 'r1' TO 'r1'; -- simple loop: r1 => r1
GRANT 'r2' TO 'u2';
GRANT 'u2' TO 'r2'; -- mixed user/role loop: u2 => r2 => u2
允许循环授予引用,但不会向受让人添加任何新的权限或角色,因为用户或角色已经拥有其权限和角色。
GRANT
可以使用 AS
子句指定有关用于语句执行的权限上下文的其他信息。这种语法在 SQL 级别可见,尽管其主要目的是通过使这些限制出现在二进制日志中,从而使部分撤销施加的授予者权限限制在所有授予者节点之间进行一致的复制。有关部分撤销的信息,请参见 第 8.2.12 节,“使用部分撤销进行权限限制”。user
[WITH ROLE]
当指定了 AS
子句时,语句执行将考虑与命名用户关联的任何权限限制,包括 user
WITH ROLE
(如果存在)指定的 所有角色。结果是,语句实际授予的权限可能会相对于指定的权限减少。
以下条件适用于 AS
子句user
AS
仅在命名user
具有权限限制时才有效(这意味着partial_revokes
系统变量已启用)。如果给出了
WITH ROLE
,则必须将所有命名的角色授予命名user
。命名
user
应为 MySQL 帐户,指定为'
、user_name
'@'host_name
'CURRENT_USER
或CURRENT_USER()
。当前用户可以与WITH ROLE
同时命名,以防执行用户希望GRANT
使用一组可能与当前会话中活动的角色不同的角色应用来执行。AS
不能用于获得执行GRANT
语句的用户不拥有的权限。执行用户必须至少具有要授予的权限,但AS
子句只能限制授予的权限,而不能升级权限。关于要授予的权限,
AS
不能指定与执行GRANT
语句的用户相比具有更多权限(更少的限制)的用户/角色组合。允许AS
用户/角色组合具有比执行用户更多的权限,但前提是语句不授予这些额外的权限。AS
仅支持授予全局权限 (ON *.*
)。AS
不支持PROXY
授予。
以下示例说明了 AS
子句的效果。创建一个具有某些全局权限以及对这些权限的限制的用户 u1
CREATE USER u1;
GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
REVOKE INSERT, UPDATE ON schema1.* FROM u1;
REVOKE SELECT ON schema2.* FROM u1;
还创建一个解除某些权限限制的角色 r1
,并将该角色授予 u1
CREATE ROLE r1;
GRANT INSERT ON schema1.* TO r1;
GRANT SELECT ON schema2.* TO r1;
GRANT r1 TO u1;
现在,使用没有自身权限限制的帐户,向多个用户授予相同的全局权限集,但每个用户都受到 AS
子句施加的不同限制,并检查实际授予了哪些权限。
此处的
GRANT
语句没有AS
子句,因此授予的权限与指定的权限完全相同mysql> CREATE USER u2; mysql> GRANT SELECT, INSERT, UPDATE ON *.* TO u2; mysql> SHOW GRANTS FOR u2; +-------------------------------------------------+ | Grants for u2@% | +-------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE ON *.* TO `u2`@`%` | +-------------------------------------------------+
此处的
GRANT
语句具有AS
子句,因此授予的权限是指定的权限,但应用了u1
的限制mysql> CREATE USER u3; mysql> GRANT SELECT, INSERT, UPDATE ON *.* TO u3 AS u1; mysql> SHOW GRANTS FOR u3; +----------------------------------------------------+ | Grants for u3@% | +----------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE ON *.* TO `u3`@`%` | | REVOKE INSERT, UPDATE ON `schema1`.* FROM `u3`@`%` | | REVOKE SELECT ON `schema2`.* FROM `u3`@`%` | +----------------------------------------------------+
如前所述,
AS
子句只能添加权限限制,不能升级权限。因此,尽管u1
拥有DELETE
权限,但该权限不包含在授予的权限中,因为语句没有指定授予DELETE
。此处的
GRANT
语句的AS
子句为u1
激活角色r1
。该角色消除了u1
上的某些限制。因此,授予的权限具有一些限制,但不像前面的GRANT
语句那样多mysql> CREATE USER u4; mysql> GRANT SELECT, INSERT, UPDATE ON *.* TO u4 AS u1 WITH ROLE r1; mysql> SHOW GRANTS FOR u4; +-------------------------------------------------+ | Grants for u4@% | +-------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE ON *.* TO `u4`@`%` | | REVOKE UPDATE ON `schema1`.* FROM `u4`@`%` | +-------------------------------------------------+
如果 GRANT
语句包含 AS
子句,则会忽略执行该语句的用户的权限限制(而不是像没有 user
AS
子句那样应用)。
可选的 WITH
子句用于允许用户向其他用户授予权限。 WITH GRANT OPTION
子句赋予用户向其他用户授予他们在指定权限级别拥有的任何权限的能力。
要向帐户授予 GRANT OPTION
权限,而不更改其其他权限,请执行以下操作
GRANT USAGE ON *.* TO 'someuser'@'somehost' WITH GRANT OPTION;
请谨慎选择向谁授予 GRANT OPTION
权限,因为两个具有不同权限的用户可能能够合并权限!
您不能授予您自己没有的权限给另一个用户; GRANT OPTION
权限使您只能分配您自己拥有的权限。
请注意,当您在特定权限级别向用户授予 GRANT OPTION
权限时,该用户在该级别拥有的任何权限(或将来可能获得的任何权限)也可以由该用户授予其他用户。假设您向用户授予了数据库上的 INSERT
权限。如果您随后授予数据库上的 SELECT
权限并指定 WITH GRANT OPTION
,则该用户不仅可以将 SELECT
权限授予其他用户,还可以授予 INSERT
。如果您随后授予该用户数据库上的 UPDATE
权限,则该用户可以授予 INSERT
、SELECT
和 UPDATE
。
对于非管理员用户,您不应该全局或针对 mysql
系统模式授予 ALTER
权限。如果您这样做,用户可能会尝试通过重命名表来破坏权限系统!
有关与特定权限相关的安全风险的更多信息,请参见 第 8.2.2 节,“MySQL 提供的权限”。
MySQL 和标准 SQL 版本的 GRANT
之间的最大区别是
MySQL 将权限与主机名和用户名组合关联,而不是仅与用户名关联。
标准 SQL 没有全局或数据库级别的权限,也不支持 MySQL 支持的所有权限类型。
MySQL 不支持标准 SQL 的
UNDER
权限。标准 SQL 权限以层次结构方式构建。如果您删除用户,则该用户已授予的所有权限都将被撤销。如果您使用
DROP USER
,在 MySQL 中也是如此。请参见 第 15.7.1.5 节,“DROP USER 语句”。在标准 SQL 中,当您删除表时,该表的所有权限都将被撤销。在标准 SQL 中,当您撤销权限时,所有基于该权限授予的权限也将被撤销。在 MySQL 中,可以使用
DROP USER
或REVOKE
语句删除权限。在 MySQL 中,可以仅针对表中的一些列拥有
INSERT
权限。在这种情况下,您仍然可以在表上执行INSERT
语句,前提是您仅对您拥有INSERT
权限的那些列插入值。如果未启用严格 SQL 模式,则将省略的列设置为其隐式默认值。在严格模式下,如果任何省略的列没有默认值,则语句将被拒绝。(标准 SQL 要求您对所有列拥有INSERT
权限。)有关严格 SQL 模式和隐式默认值的更多信息,请参见 第 7.1.11 节,“服务器 SQL 模式” 和 第 13.6 节,“数据类型默认值”。