文档首页
MySQL 8.4 参考手册
8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

8.2.19 代理用户8.2.19 Proxy Users

MySQL 服务器使用认证插件来验证客户端连接。用于验证某个连接的插件可能会要求将连接的(外部)用户视为不同的用户以进行权限检查。这使得外部用户可以作为第二个用户的代理;也就是说,承担第二个用户的权限:The MySQL server authenticates client connections using authentication plugins. The plugin that authenticates a given connection may request that the connecting (external) user be treated as a different user for privilege-checking purposes. This enables the external user to be a proxy for the second user; that is, to assume the privileges of the second user:

  • 外部用户是一个“代理用户”(可以冒充或被识别为其他用户的用户)。The external user is a “proxy user” (a user who can impersonate or become known as another user).

  • 第二个用户是一个“被代理用户”(其身份和权限可以被代理用户承担的用户)。The second user is a “proxied user” (a user whose identity and privileges can be assumed by a proxy user).

本节描述了代理用户功能的工作原理。有关身份验证插件的一般信息,请参阅 第 8.2.17 节,“可插拔身份验证”。有关特定插件的信息,请参阅 第 8.4.1 节,“身份验证插件”。有关编写支持代理用户的身份验证插件的信息,请参阅 在身份验证插件中实现代理用户支持。This section describes how the proxy user capability works. For general information about authentication plugins, see Section 8.2.17, “Pluggable Authentication”. For information about specific plugins, see Section 8.4.1, “Authentication Plugins”. For information about writing authentication plugins that support proxy users, see Implementing Proxy User Support in Authentication Plugins.

Note

通过代理获得的一个管理优势是,DBA 可以设置一个具备特定权限的单一账户,然后启用多个代理用户拥有这些权限,而不必单独为每个用户分配权限。作为代理用户的替代方案,DBA 可能会发现角色提供了一种将用户映射到特定命名权限集合的合适方式。每个用户可以被授予一个指定角色,从而实际上获得适当的权限集合。参见 第 8.2.10 节,“使用角色”。One administrative benefit to be gained by proxying is that the DBA can set up a single account with a set of privileges and then enable multiple proxy users to have those privileges without having to assign the privileges individually to each of those users. As an alternative to proxy users, DBAs may find that roles provide a suitable way to map users onto specific sets of named privileges. Each user can be granted a given single role to, in effect, be granted the appropriate set of privileges. See Section 8.2.10, “Using Roles”.

代理用户支持的要求Requirements for Proxy User Support

要对给定的身份验证插件进行代理,必须满足以下条件:For proxying to occur for a given authentication plugin, these conditions must be satisfied:

  • 必须支持代理,无论是由插件自身支持,还是由 MySQL 服务器代表插件支持。在后一种情况下,可能需要显式启用服务器支持;请参见 代理用户映射的服务器支持。Proxying must be supported, either by the plugin itself, or by the MySQL server on behalf of the plugin. In the latter case, server support may need to be enabled explicitly; see Server Support for Proxy User Mapping.

  • 外部代理用户的账户必须设置为由插件进行认证。使用 CREATE USER 语句将账户与身份验证插件关联,或使用 ALTER USER 更改其插件。The account for the external proxy user must be set up to be authenticated by the plugin. Use the CREATE USER statement to associate an account with an authentication plugin, or ALTER USER to change its plugin.

  • 被代理用户的账户必须存在,并且被授予由代理用户承担的权限。为此,请使用 CREATE USER 和 GRANT 语句。The account for the proxied user must exist and be granted the privileges to be assumed by the proxy user. Use the CREATE USER and GRANT statements for this.

  • 通常,代理用户被配置成只能在代理场景中使用,而不能直接登录。Normally, the proxied user is configured so that it can be used only in proxying scenarios and not for direct logins.

  • 代理用户账户必须对被代理账户具有 PROXY 权限。为此,请使用 GRANT 语句。The proxy user account must have the PROXY privilege for the proxied account. Use the GRANT statement for this.

  • 为了使连接到代理账户的客户端被视为代理用户,认证插件必须返回与客户端用户名不同的用户名,以指示被代理账户的用户名,该账户定义了代理用户将要继承的权限。For a client connecting to the proxy account to be treated as a proxy user, the authentication plugin must return a user name different from the client user name, to indicate the user name of the proxied account that defines the privileges to be assumed by the proxy user.

    或者,对于由服务器提供代理映射的插件,代理用户由代理用户所持有的 PROXY 权限确定。Alternatively, for plugins that are provided proxy mapping by the server, the proxied user is determined from the PROXY privilege held by the proxy user.

代理机制只允许将外部客户端用户名映射到被代理的用户名。没有提供映射主机名的功能:The proxy mechanism permits mapping only the external client user name to the proxied user name. There is no provision for mapping host names:

  • 当客户端连接到服务器时,服务器会根据客户端程序传递的用户名以及客户端连接的主机来确定正确的账户。When a client connects to the server, the server determines the proper account based on the user name passed by the client program and the host from which the client connects.

  • 如果该账户是代理账户,服务器会尝试通过使用认证插件返回的用户名和代理账户的主机名来找到匹配的被代理账户,以确定合适的被代理账户。被代理账户中的主机名会被忽略。If that account is a proxy account, the server attempts to determine the appropriate proxied account by finding a match for a proxied account using the user name returned by the authentication plugin and the host name of the proxy account. The host name in the proxied account is ignored.

简单代理用户示例Simple Proxy User Example

请考虑以下账户定义:Consider the following account definitions:

-- create proxy account
CREATE USER 'employee_ext'@'localhost'
  IDENTIFIED WITH my_auth_plugin
  AS 'my_auth_string';

-- create proxied account and grant its privileges;
-- use mysql_no_login plugin to prevent direct login
CREATE USER 'employee'@'localhost'
  IDENTIFIED WITH mysql_no_login;
GRANT ALL
  ON employees.*
  TO 'employee'@'localhost';

-- grant to proxy account the
-- PROXY privilege for proxied account
GRANT PROXY
  ON 'employee'@'localhost'
  TO 'employee_ext'@'localhost';

当客户端以 employee_ext 身份从本地主机连接时,MySQL 使用名为 my_auth_plugin 的插件进行身份验证。假设 my_auth_plugin 根据 'my_auth_string' 的内容,并可能通过查询某些外部身份验证系统,向服务器返回一个用户名 employee。名称 employee 与 employee_ext 不同,因此返回 employee 实际上是向服务器请求,在权限检查时,将 employee_ext 外部用户视为 employee 本地用户。When a client connects as employee_ext from the local host, MySQL uses the plugin named my_auth_plugin to perform authentication. Suppose that my_auth_plugin returns a user name of employee to the server, based on the content of 'my_auth_string' and perhaps by consulting some external authentication system. The name employee differs from employee_ext, so returning employee serves as a request to the server to treat the employee_ext external user, for purposes of privilege checking, as the employee local user.

在这种情况下,employee_ext 是代理用户,而 employee 是被代理用户。In this case, employee_ext is the proxy user and employee is the proxied user.

服务器通过检查employee(代理用户)是否拥有employee_ext(被代理用户)的employee_ext权限来验证代理认证是否对于PROXY用户可用。如果未授予此权限,则会发生错误。否则,employee假定employee_ext的权限。employee服务器通过employee_ext执行的客户端会话中的语句与employee授予的权限进行检查。在这种情况下,employee_ext can access tables in the employees database.The server verifies that proxy authentication for employee is possible for the employee_ext user by checking whether employee_ext (the proxy user) has the PROXY privilege for employee (the proxied user). If this privilege has not been granted, an error occurs. Otherwise, employee_ext assumes the privileges of employee. The server checks statements executed during the client session by employee_ext against the privileges granted to employee. In this case, employee_ext can access tables in the employees database.

被代理的账户,employee,使用 mysql_no_login 认证插件来防止客户端直接使用该账户登录。(这假设该插件已安装。有关说明,请参见 第 8.4.1.9 节,“不可登录的可插拔认证”。)有关保护被代理账户免于直接使用的替代方法,请参见 防止直接登录被代理账户。The proxied account, employee, uses the mysql_no_login authentication plugin to prevent clients from using the account to log in directly. (This assumes that the plugin is installed. For instructions, see Section 8.4.1.9, “No-Login Pluggable Authentication”.) For alternative methods of protecting proxied accounts against direct use, see Preventing Direct Login to Proxied Accounts.

当发生代理时,可以使用 USER() 和 CURRENT_USER() 函数来查看连接用户(代理用户)与当前会话中适用权限的账户(被代理用户)之间的差异。对于刚刚描述的示例,这些函数返回以下值:When proxying occurs, the USER() and CURRENT_USER() functions can be used to see the difference between the connecting user (the proxy user) and the account whose privileges apply during the current session (the proxied user). For the example just described, those functions return these values:

mysql> SELECT USER(), CURRENT_USER();
+------------------------+--------------------+
| USER()                 | CURRENT_USER()     |
+------------------------+--------------------+
| employee_ext@localhost | employee@localhost |
+------------------------+--------------------+

在创建代理用户帐户的 CREATE USER 语句中,IDENTIFIED WITH 子句用于指定支持代理的身份验证插件,后面可选择性跟随一个 AS 'auth_string' 子句,用于指定服务器在用户连接时传递给插件的字符串。如果存在,该字符串提供的信息有助于插件确定如何将代理(外部)客户端用户名映射到被代理的用户名。是否需要 AS 子句由每个插件决定。如果需要,则身份验证字符串的格式取决于插件打算如何使用它。有关插件接受的身份验证字符串值的信息,请查阅相应插件的文档。In the CREATE USER statement that creates the proxy user account, the IDENTIFIED WITH clause that names the proxy-supporting authentication plugin is optionally followed by an AS 'auth_string' clause specifying a string that the server passes to the plugin when the user connects. If present, the string provides information that helps the plugin determine how to map the proxy (external) client user name to a proxied user name. It is up to each plugin whether it requires the AS clause. If so, the format of the authentication string depends on how the plugin intends to use it. Consult the documentation for a given plugin for information about the authentication string values it accepts.

防止对代理账户的直接登录Preventing Direct Login to Proxied Accounts

代理账户通常仅打算通过代理账户使用。也就是说,客户端使用代理账户连接,然后被映射并承担适当的被代理用户的权限。Proxied accounts generally are intended to be used only by means of proxy accounts. That is, clients connect using a proxy account, then are mapped onto and assume the privileges of the appropriate proxied user.

有多种方法可以确保代理账户不能被直接使用:There are multiple ways to ensure that a proxied account cannot be used directly:

  • 将该账户与 mysql_no_login 认证插件关联。在此情况下,该账户在任何情况下都不能用于直接登录。这假设该插件已安装。有关说明,请参见 第 8.4.1.9 节,“不可登录可插拔认证”。Associate the account with the mysql_no_login authentication plugin. In this case, the account cannot be used for direct logins under any circumstances. This assumes that the plugin is installed. For instructions, see Section 8.4.1.9, “No-Login Pluggable Authentication”.

  • 在创建账户时包括 ACCOUNT LOCK 选项。请参阅 第 15.7.1.3 节,“CREATE USER 语句”。使用此方法时,还要包括一个密码,以便如果账户稍后被解锁,也不能在没有密码的情况下访问。(如果启用了 validate_password 组件,即使账户被锁定,也不允许创建没有密码的账户。请参阅 第 8.4.3 节,“密码验证组件”。)Include the ACCOUNT LOCK option when you create the account. See Section 15.7.1.3, “CREATE USER Statement”. With this method, also include a password so that if the account is unlocked later, it cannot be accessed with no password. (If the validate_password component is enabled, creating an account without a password is not permitted, even if the account is locked. See Section 8.4.3, “The Password Validation Component”.)

  • 创建账户并设置密码,但不要告诉其他人密码。如果你不让任何人知道账户的密码,客户端就不能直接使用它连接到 MySQL 服务器。Create the account with a password but do not tell anyone else the password. If you do not let anyone know the password for the account, clients cannot use it to connect directly to the MySQL server.

授予和撤销 PROXY 权限Granting and Revoking the PROXY Privilege

PROXY 权限是允许外部用户以另一个用户的身份连接并拥有其权限所必需的。要授予此权限,请使用 GRANT 语句。例如:The PROXY privilege is needed to enable an external user to connect as and have the privileges of another user. To grant this privilege, use the GRANT statement. For example:

GRANT PROXY ON 'proxied_user' TO 'proxy_user';

该语句会在 mysql.proxies_priv 授权表中创建一行。The statement creates a row in the mysql.proxies_priv grant table.

在连接时,proxy_user 必须表示一个有效的外部认证 MySQL 用户,而 proxied_user 必须表示一个有效的本地认证用户。否则,连接尝试将失败。At connect time, proxy_user must represent a valid externally authenticated MySQL user, and proxied_user must represent a valid locally authenticated user. Otherwise, the connection attempt fails.

相应的 REVOKE 语法为:The corresponding REVOKE syntax is:

REVOKE PROXY ON 'proxied_user' FROM 'proxy_user';

MySQL GRANT 和 REVOKE 语法扩展照常工作。示例:MySQL GRANT and REVOKE syntax extensions work as usual. Examples:

-- grant PROXY to multiple accounts
GRANT PROXY ON 'a' TO 'b', 'c', 'd';

-- revoke PROXY from multiple accounts
REVOKE PROXY ON 'a' FROM 'b', 'c', 'd';

-- grant PROXY to an account and enable the account to grant
-- PROXY to the proxied account
GRANT PROXY ON 'a' TO 'd' WITH GRANT OPTION;

-- grant PROXY to default proxy account
GRANT PROXY ON 'a' TO ''@'';

在以下情况下可以授予 PROXY 权限:The PROXY privilege can be granted in these cases:

  • 由对 proxied_user 拥有 GRANT PROXY ... WITH GRANT OPTION 的用户授予。By a user that has GRANT PROXY ... WITH GRANT OPTION for proxied_user.

  • By proxied_user for itself: The value of USER() must exactly match CURRENT_USER()以及proxied_user, for both the user name and host name parts of the account name.By proxied_user for itself: The value of USER() must exactly match CURRENT_USER() and proxied_user, for both the user name and host name parts of the account name.

在 MySQL 安装过程中创建的初始 root account 的 PROXY ... WITH GRANT OPTION ''@'',即对所有用户和主机。这使得 root设置代理用户,并将设置代理用户的权限委托给其他账户。例如,root 可以做到:The initial root account created during MySQL installation has the PROXY ... WITH GRANT OPTION privilege for ''@'', that is, for all users and all hosts. This enables root to set up proxy users, as well as to delegate to other accounts the authority to set up proxy users. For example, root can do this:

CREATE USER 'admin'@'localhost'
  IDENTIFIED BY 'admin_password';
GRANT PROXY
  ON ''@''
  TO 'admin'@'localhost'
  WITH GRANT OPTION;

这些语句创建了一个 admin 用户,该用户可以管理所有 GRANT PROXY 映射。例如,admin 可以执行以下操作:Those statements create an admin user that can manage all GRANT PROXY mappings. For example, admin can do this:

GRANT PROXY ON sally TO joe;

默认代理用户Default Proxy Users

要指定某些或所有用户应使用给定的认证插件进行连接,请创建一个空用户名和主机名(''@'')的 “blank” MySQL 账户,将其与该插件关联,并让插件返回实际认证的用户名(如果与空用户不同)。假设存在一个名为 ldap_auth 的插件,它实现了 LDAP 认证并将连接的用户映射到开发者或管理者账户。要设置将用户代理到这些账户,请使用以下语句:To specify that some or all users should connect using a given authentication plugin, create a “blank” MySQL account with an empty user name and host name (''@''), associate it with that plugin, and let the plugin return the real authenticated user name (if different from the blank user). Suppose that there exists a plugin named ldap_auth that implements LDAP authentication and maps connecting users onto either a developer or manager account. To set up proxying of users onto these accounts, use the following statements:

-- create default proxy account
CREATE USER ''@''
  IDENTIFIED WITH ldap_auth
  AS 'O=Oracle, OU=MySQL';

-- create proxied accounts; use
-- mysql_no_login plugin to prevent direct login
CREATE USER 'developer'@'localhost'
  IDENTIFIED WITH mysql_no_login;
CREATE USER 'manager'@'localhost'
  IDENTIFIED WITH mysql_no_login;

-- grant to default proxy account the
-- PROXY privilege for proxied accounts
GRANT PROXY
  ON 'manager'@'localhost'
  TO ''@'';
GRANT PROXY
  ON 'developer'@'localhost'
  TO ''@'';

现在假设一个客户端按如下方式连接:Now assume that a client connects as follows:

$> mysql --user=myuser --password ...
Enter password: myuser_password

服务器未找到将 myuser 定义为 MySQL 用户,但由于存在一个空用户账户 (''@'') 与客户端用户名和主机名匹配,服务器使用该账户对客户端进行身份验证。服务器调用 ldap_auth 认证插件,并将 myuser 和 myuser_password 作为用户名和密码传递给它。The server does not find myuser defined as a MySQL user, but because there is a blank user account (''@'') that matches the client user name and host name, the server authenticates the client against that account. The server invokes the ldap_auth authentication plugin and passes myuser and myuser_password to it as the user name and password.

如果 ldap_auth 插件在 LDAP 目录中发现 myuser_password 不是 myuser 的正确密码,认证将失败,服务器会拒绝连接。If the ldap_auth plugin finds in the LDAP directory that myuser_password is not the correct password for myuser, authentication fails and the server rejects the connection.

如果密码正确,并且 ldap_auth 发现 myuser 是开发人员,它会向 MySQL 服务器返回用户名 developer,而不是 myuser。返回与客户端用户名 myuser 不同的用户名,向服务器表示应将 myuser 视为代理。服务器验证 ''@'' 是否可以以 developer 身份进行认证(因为 ''@'' 拥有执行此操作的 PROXY 权限)并接受连接。会话继续,myuser 拥有被代理用户 developer 的权限。(这些权限应由 DBA 使用 GRANT 语句设置,本例未显示。)USER() 和 CURRENT_USER() 函数返回这些值:If the password is correct and ldap_auth finds that myuser is a developer, it returns the user name developer to the MySQL server, rather than myuser. Returning a user name different from the client user name of myuser signals to the server that it should treat myuser as a proxy. The server verifies that ''@'' can authenticate as developer (because ''@'' has the PROXY privilege to do so) and accepts the connection. The session proceeds with myuser having the privileges of the developer proxied user. (These privileges should be set up by the DBA using GRANT statements, not shown.) The USER() and CURRENT_USER() functions return these values:

mysql> SELECT USER(), CURRENT_USER();
+------------------+---------------------+
| USER()           | CURRENT_USER()      |
+------------------+---------------------+
| myuser@localhost | developer@localhost |
+------------------+---------------------+

如果插件在 LDAP 目录中发现 myuser 是管理员,它会返回 manager 作为用户名,并且会话将继续,myuser 拥有作为 manager 代理用户的权限。If the plugin instead finds in the LDAP directory that myuser is a manager, it returns manager as the user name and the session proceeds with myuser having the privileges of the manager proxied user.

mysql> SELECT USER(), CURRENT_USER();
+------------------+-------------------+
| USER()           | CURRENT_USER()    |
+------------------+-------------------+
| myuser@localhost | manager@localhost |
+------------------+-------------------+

为了简化,外部认证不能是多级的:在前面的例子中,既没有考虑developer的凭据,也没有考虑manager的凭据。然而,如果客户端尝试直接以developer或manager账号连接并进行身份验证,它们仍然会被使用,这就是为什么这些被代理的账号应当防止直接登录(参见 防止对被代理账号的直接登录)。For simplicity, external authentication cannot be multilevel: Neither the credentials for developer nor those for manager are taken into account in the preceding example. However, they are still used if a client tries to connect and authenticate directly as the developer or manager account, which is why those proxied accounts should be protected against direct login (see Preventing Direct Login to Proxied Accounts).

默认代理用户与匿名用户冲突Default Proxy User and Anonymous User Conflicts

如果您打算创建默认代理用户,请检查是否存在其他优先于默认代理用户的 “匹配任何用户” 账户,因为它们可能会阻止该用户按预期工作。If you intend to create a default proxy user, check for other existing “match any user” accounts that take precedence over the default proxy user because they can prevent that user from working as intended.

在前述讨论中,默认代理用户账户在主机部分具有 '',它可以匹配任何主机。如果您设置了默认代理用户,请注意还要检查是否存在具有相同用户部分且主机部分为 '%' 的非代理账户,因为 '%' 同样匹配任何主机,但根据服务器用于内部排序账户行的规则,它比 '' 优先(参见 第 8.2.6 节,“访问控制,第 1 阶段:连接验证”)。In the preceding discussion, the default proxy user account has '' in the host part, which matches any host. If you set up a default proxy user, take care to also check whether nonproxy accounts exist with the same user part and '%' in the host part, because '%' also matches any host, but has precedence over '' by the rules that the server uses to sort account rows internally (see Section 8.2.6, “Access Control, Stage 1: Connection Verification”).

假设一个 MySQL 安装包含以下两个账户:Suppose that a MySQL installation includes these two accounts:

-- create default proxy account
CREATE USER ''@''
  IDENTIFIED WITH some_plugin
  AS 'some_auth_string';
-- create anonymous account
CREATE USER ''@'%'
  IDENTIFIED BY 'anon_user_password';

第一个账户(''@'')被用作默认代理用户,用于为那些没有匹配更具体账户的用户认证连接。第二个账户(''@'%')是匿名用户账户,例如,它可能被创建用于允许没有自己账户的用户匿名连接。The first account (''@'') is intended as the default proxy user, used to authenticate connections for users who do not otherwise match a more-specific account. The second account (''@'%') is an anonymous-user account, which might have been created, for example, to enable users without their own account to connect anonymously.

两个账户具有相同的用户部分(''),它匹配任何用户。每个账户都有一个主机部分,匹配任何主机。尽管如此,在连接尝试中账户匹配有优先级,因为匹配规则会将 '%' 放在 '' 之前。对于不匹配任何更具体账户的账户,服务器会尝试根据 ''@'%'(匿名用户)进行身份验证,而不是 ''@''(默认代理用户)。因此,默认代理账户从不使用。Both accounts have the same user part (''), which matches any user. And each account has a host part that matches any host. Nevertheless, there is a priority in account matching for connection attempts because the matching rules sort a host of '%' ahead of ''. For accounts that do not match any more-specific account, the server attempts to authenticate them against ''@'%' (the anonymous user) rather than ''@'' (the default proxy user). As a result, the default proxy account is never used.

为避免此问题,请使用以下策略之一:To avoid this problem, use one of the following strategies:

  • 删除匿名账户,以免与默认代理用户发生冲突。Remove the anonymous account so that it does not conflict with the default proxy user.

  • 使用一个更具体的默认代理用户,使其优先于匿名用户匹配。例如,要仅允许 localhost 代理连接,请使用 ''@'localhost':Use a more-specific default proxy user that matches ahead of the anonymous user. For example, to permit only localhost proxy connections, use ''@'localhost':

    CREATE USER ''@'localhost'
      IDENTIFIED WITH some_plugin
      AS 'some_auth_string';
    

    此外,将任何 GRANT PROXY 语句中的代理用户指定为 ''@'localhost' 而不是 ''@''。In addition, modify any GRANT PROXY statements to name ''@'localhost' rather than ''@'' as the proxy user.

    请注意,这种策略会阻止匿名用户从 localhost 进行连接。Be aware that this strategy prevents anonymous-user connections from localhost.

  • 使用具名的默认账号,而不是匿名默认账号。有关此技术的示例,请参阅使用 authentication_windows 插件的说明。见 第 8.4.1.6 节,“Windows 可插拔认证”。Use a named default account rather than an anonymous default account. For an example of this technique, consult the instructions for using the authentication_windows plugin. See Section 8.4.1.6, “Windows Pluggable Authentication”.

  • 创建多个代理用户,一个用于本地连接,另一个用于“其他所有”(远程连接)。当本地用户应具有不同于远程用户的权限时,这尤其有用。Create multiple proxy users, one for local connections and one for “everything else” (remote connections). This can be useful particularly when local users should have different privileges from remote users.

    创建代理用户:Create the proxy users:

    -- create proxy user for local connections
    CREATE USER ''@'localhost'
      IDENTIFIED WITH some_plugin
      AS 'some_auth_string';
    -- create proxy user for remote connections
    CREATE USER ''@'%'
      IDENTIFIED WITH some_plugin
      AS 'some_auth_string';
    

    创建被代理用户:Create the proxied users:

    -- create proxied user for local connections
    CREATE USER 'developer'@'localhost'
      IDENTIFIED WITH mysql_no_login;
    -- create proxied user for remote connections
    CREATE USER 'developer'@'%'
      IDENTIFIED WITH mysql_no_login;
    

    为每个代理账户授予相应被代理账户的PROXY权限:Grant to each proxy account the PROXY privilege for the corresponding proxied account:

    GRANT PROXY
      ON 'developer'@'localhost'
      TO ''@'localhost';
    GRANT PROXY
      ON 'developer'@'%'
      TO ''@'%';
    

    最后,为本地和远程代理用户授予适当的权限(未显示)。Finally, grant appropriate privileges to the local and remote proxied users (not shown).

    假设 some_plugin/'some_auth_string' 组合导致 some_plugin 将客户端用户名映射为 developer。本地连接匹配 ''@'localhost' 代理用户,该用户映射到 'developer'@'localhost' 被代理用户。远程连接匹配 ''@'%' 代理用户,该用户映射到 'developer'@'%' 被代理用户。Assume that the some_plugin/'some_auth_string' combination causes some_plugin to map the client user name to developer. Local connections match the ''@'localhost' proxy user, which maps to the 'developer'@'localhost' proxied user. Remote connections match the ''@'%' proxy user, which maps to the 'developer'@'%' proxied user.

服务器对代理用户映射的支持Server Support for Proxy User Mapping

一些认证插件为自己实现了代理用户映射(例如,PAM 和 Windows 认证插件)。其他认证插件默认不支持代理用户。在这些插件中,有些可以请求 MySQL 服务器根据授予的代理权限映射代理用户:mysql_native_password(已弃用)、sha256_password(已弃用)。如果启用了 check_proxy_users 系统变量,服务器会为任何提出此类请求的认证插件执行代理用户映射:Some authentication plugins implement proxy user mapping for themselves (for example, the PAM and Windows authentication plugins). Other authentication plugins do not support proxy users by default. Of these, some can request that the MySQL server itself map proxy users according to granted proxy privileges: mysql_native_password (deprecated), sha256_password (deprecated). If the check_proxy_users system variable is enabled, the server performs proxy user mapping for any authentication plugins that make such a request:

  • 默认情况下,check_proxy_users 是禁用的,因此即使是请求服务器支持代理用户的认证插件,服务器也不会执行任何代理用户映射。By default, check_proxy_users is disabled, so the server performs no proxy user mapping even for authentication plugins that request server support for proxy users.

  • 如果启用了 check_proxy_users,可能还需要启用插件特定的系统变量,以利用服务器的代理用户映射支持:If check_proxy_users is enabled, it may also be necessary to enable a plugin-specific system variable to take advantage of server proxy user mapping support:

例如,要启用所有上述功能,请在 my.cnf 文件中使用以下行启动服务器:For example, to enable all the preceding capabilities, start the server with these lines in the my.cnf file:

[mysqld]
check_proxy_users=ON
mysql_native_password_proxy_users=ON
sha256_password_proxy_users=ON

假设已启用相关系统变量,按照常规使用 CREATE USER 创建代理用户,然后将 PROXY 权限授予单个其他账户,以使其被视为被代理用户。当服务器收到代理用户的成功连接请求时,它会发现该用户具有 PROXY 权限,并使用该权限来确定适当的被代理用户。Assuming that the relevant system variables have been enabled, create the proxy user as usual using CREATE USER, then grant it the PROXY privilege to a single other account to be treated as the proxied user. When the server receives a successful connection request for the proxy user, it finds that the user has the PROXY privilege and uses it to determine the proper proxied user.

-- create proxy account
CREATE USER 'proxy_user'@'localhost'
  IDENTIFIED WITH mysql_native_password
  BY 'password';

-- create proxied account and grant its privileges;
-- use mysql_no_login plugin to prevent direct login
CREATE USER 'proxied_user'@'localhost'
  IDENTIFIED WITH mysql_no_login;
-- grant privileges to proxied account
GRANT ...
  ON ...
  TO 'proxied_user'@'localhost';

-- grant to proxy account the
-- PROXY privilege for proxied account
GRANT PROXY
  ON 'proxied_user'@'localhost'
  TO 'proxy_user'@'localhost';

要使用代理账户,请使用其名称和密码连接到服务器:To use the proxy account, connect to the server using its name and password:

$> mysql -u proxy_user -p
Enter password: (enter proxy_user password here)

认证成功,服务器发现 proxy_user 对 proxied_user 拥有 PROXY 权限,会议以 proxy_user 拥有 proxied_user 的权限继续进行。Authentication succeeds, the server finds that proxy_user has the PROXY privilege for proxied_user, and the session proceeds with proxy_user having the privileges of proxied_user.

由服务器执行的代理用户映射受以下限制:Proxy user mapping performed by the server is subject to these restrictions:

  • 服务器不会对匿名用户进行代理,也不会代理来自匿名用户的请求,即使授予了相关的 PROXY 特权。The server does not proxy to or from an anonymous user, even if the associated PROXY privilege is granted.

  • 当单个账户被授予多个代理账户的代理权限时,服务器代理用户映射是非确定性的。因此,不建议授予单个账户多个代理账户的代理权限。When a single account has been granted proxy privileges for more than one proxied account, server proxy user mapping is nondeterministic. Therefore, granting to a single account proxy privileges for multiple proxied accounts is discouraged.

代理用户系统变量Proxy User System Variables

两个系统变量有助于跟踪代理登录过程:Two system variables help trace the proxy login process:

  • proxy_user:如果未使用代理,则此值为 NULL。否则,它表示代理用户账户。例如,如果客户端通过 ''@'' 代理账户进行认证,则此变量设置如下:proxy_user: This value is NULL if proxying is not used. Otherwise, it indicates the proxy user account. For example, if a client authenticates through the ''@'' proxy account, this variable is set as follows:

    mysql> SELECT @@proxy_user;
    +--------------+
    | @@proxy_user |
    +--------------+
    | ''@''        |
    +--------------+
    
  • external_user:有时身份验证插件可能使用外部用户来验证 MySQL 服务器。例如,在使用 Windows 本地认证时,使用 Windows API 进行身份验证的插件不需要传递登录 ID。不过,它仍然使用 Windows 用户 ID 进行身份验证。该插件可能会通过 external_user 只读会话变量将此外部用户 ID(或其前 512 个 UTF-8 字节)返回给服务器。如果插件未设置此变量,其值为 NULL。external_user: Sometimes the authentication plugin may use an external user to authenticate to the MySQL server. For example, when using Windows native authentication, a plugin that authenticates using the windows API does not need the login ID passed to it. However, it still uses a Windows user ID to authenticate. The plugin may return this external user ID (or the first 512 UTF-8 bytes of it) to the server using the external_user read-only session variable. If the plugin does not set this variable, its value is NULL.