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”)
}
GRANT
语句将权限和角色分配给 MySQL 用户帐户和角色。该 GRANT
语句有几个方面,在以下主题中描述
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: 8.4.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 服务器,您还应该将权限授予所有本地用户,作为 '
。否则,user_name
'@'localhost'mysql.user
系统表中 localhost
的匿名用户帐户将在命名用户尝试从本地计算机登录 MySQL 服务器时使用。有关详细信息,请参见 第 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
无法用于撤销这些权限。在这种情况下,必须直接操作授予表。(当 lower_case_table_names
设置时,GRANT
不会创建此类行,但此类行可能在设置该变量之前创建。 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';
在列级别(即当您使用column_list
子句时)允许的priv_type
值为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
子句使角色r1
对u1
处于活动状态。该角色取消了对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 节,“数据类型默认值”。