MySQL服务器使用身份验证插件对客户机连接进行身份验证。验证给定连接的插件可能会请求将连接(外部)用户作为不同的用户来处理,以便进行权限检查。这使得外部用户可以成为第二个用户的代理;也就是说,假设第二个用户的特权:
外部用户为a”代理用户”(可以冒充或冒充另一个用户的用户)。
第二个用户是a”代理用户”(其身份和特权可以由代理用户承担的用户)。
本节描述代理用户功能的工作原理。有关身份验证插件的一般信息,请参见第6.2.17节,“可插入认证”.有关特定插件的信息,请参见第6.4.1节“认证插件”.有关编写支持代理用户的身份验证插件的信息,请参见在认证插件中实现代理用户支持.
通过代理可以获得的一个管理好处是,DBA可以设置一个具有一组权限的帐户,然后允许多个代理用户拥有这些权限,而不必将权限分别分配给每个用户。作为代理用户的替代方案,dba可能会发现角色提供了一种将用户映射到特定命名特权集的合适方法。每个用户都可以被授予给定的单一角色,从而实际上被授予适当的特权集。看到第6.2.10节“使用角色”.
要想对一个给定的认证插件进行代理,必须满足以下条件:
代理必须支持,要么是插件本身,要么是代表插件的MySQL服务器。在后一种情况下,可能需要显式地启用服务器支持;看到代理用户映射的服务器支持.
通常,对代理用户进行了配置,使其只能用于代理场景,而不能用于直接登录。
对于连接到代理帐户的客户端要被视为代理用户,身份验证插件必须返回与客户端用户名不同的用户名,以指示代理帐户的用户名,该代理帐户定义了代理用户将承担的权限。
或者,对于由服务器提供代理映射的插件,代理用户由
代理
代理用户拥有的权限。
代理机制只允许将外部客户端用户名映射到代理用户名。没有映射主机名的规定:
当客户端连接到服务器时,服务器根据客户端程序传递的用户名和客户端连接的主机确定正确的帐户。
如果该帐户是代理帐户,则服务器使用身份验证插件返回的用户名和代理帐户的主机名查找代理帐户的匹配,从而尝试确定适当的代理帐户。代理帐户中的主机名将被忽略。
考虑以下帐户定义:
create USER 'employee_ext'@'localhost' IDENTIFIED WITH my_auth_plugin AS 'my_auth_string”;—创建代理帐户并授予其特权;CREATE USER 'employee'@'localhost' IDENTIFIED WITH mysql_no_login;授权所有员工。*“员工”@“localhost”;grant proxy ON 'employee'@'localhost' to 'employee_ext'@'localhost';
当客户端以employee_ext
从本地主机,MySQL使用名为my_auth_plugin
执行身份验证。假设my_auth_plugin
返回的用户名员工
对服务器,基于内容'
也许可以咨询一些外部认证系统。这个名字my_auth_string
'员工
不同于employee_ext
,所以返回员工
作为请求服务器处理employee_ext
用于权限检查的外部用户员工
本地用户。
在这种情况下,employee_ext
代理用户是和员工
代理用户。
服务器验证代理身份验证员工
是可能的employee_ext
通过检查用户是否employee_ext
(代理用户)具有代理
特权的员工
(代理用户)。如果未授予此特权,则会发生错误。否则,employee_ext
拥有…的特权员工
.服务器检查在客户端会话期间执行的语句employee_ext
反对被授予的特权员工
.在这种情况下,employee_ext
是否可以访问员工
数据库。
代理账户,员工
,采用mysql_no_login
认证插件,防止客户端使用该帐户直接登录。(这里假设已经安装了插件。说明,请参阅第6.4.1.9节“不可登录可插入认证”)。有关保护代理帐户不被直接使用的其他方法,请参见防止直接登录代理帐户.
发生代理时,用户()
而且CURRENT_USER ()
可以使用函数来查看连接用户(代理用户)和在当前会话期间应用特权的帐户(代理用户)之间的区别。对于刚刚描述的示例,这些函数返回以下值:
SELECT USER(), CURRENT_USER();+------------------------+--------------------+ | 用户()| CURRENT_USER () | +------------------------+--------------------+ | employee_ext@localhost | employee@localhost | +------------------------+--------------------+
在创建用户
语句,该语句创建代理用户帐户认同
子句命名支持代理的身份验证插件,后面可选地跟着为“
子句,指定用户连接时服务器传递给插件的字符串。如果存在,该字符串提供了帮助插件确定如何将代理(外部)客户端用户名映射到代理用户名的信息。这取决于每个插件是否需要auth_string
'作为
条款。如果是,认证字符串的格式取决于插件打算如何使用它。有关插件接受的身份验证字10bet官方网站符串值的信息,请参阅给定插件的文档。
代理帐户通常只打算通过代理帐户的方式使用。也就是说,客户端使用代理帐户连接,然后映射到适当的代理用户并获得其特权。
有多种方法可以确保代理帐户不能直接使用:
关联帐户与
mysql_no_login
身份验证插件。在这种情况下,该帐户在任何情况下都不能用于直接登录。这里假设已经安装了插件。说明,请参阅第6.4.1.9节“不可登录可插入认证”.包括
账户锁定
选项。看到第13.7.1.3节,“CREATE USER语句”.使用这种方法时,还要加上密码,这样,如果后来帐户被解锁,没有密码就无法访问。(如果validate_password
组件时,不允许创建无密码的帐户,即使该帐户被锁定。看到第6.4.3节“密码验证组件”)。创建一个有密码的帐户,但不要告诉任何人这个密码。如果您不让任何人知道该帐户的密码,客户端就不能使用它直接连接到MySQL服务器。
的代理
需要特权才能使外部用户以另一个用户的身份连接并拥有另一个用户的特权。要授予此特权,请使用格兰特
声明。例如:
授予代理'proxied_user”到“proxy_user”;
类中创建一行mysql.proxies_priv
授权表。
在连接时,proxy_user
必须代表一个有效的外部认证MySQL用户,和proxied_user
必须表示有效的本地身份验证用户。否则,连接失败。
相应的撤销
语法是:
撤销'上的代理proxied_user“从”proxy_user”;
授权代理'a'到'b', 'c', 'd';从'b', 'c', 'd'中撤销代理—授予代理给一个帐户,并使该帐户授予—代理给代理帐户授予代理上的'a'到'd'与授予选项;授代理到默认代理帐户“@”;
的代理
在以下情况下可以授予特权:
由一个用户
授权代理…使用GRANT选项
为proxied_user
.通过
proxied_user
的价值用户()
必须精确匹配CURRENT_USER ()
而且proxied_user
,对于帐户名的用户名和主机名部分。
最初的根
MySQL安装过程中创建的帐户具有代理…使用GRANT选项
特权的“@”
,即针对所有用户和所有主机。这使根
设置代理用户,以及将设置代理用户的权限委派给其他帐户。例如,根
可以这样做:
创建用户“admin”@“localhost”admin_password”;授权代理“@”上的“admin”@“localhost”与授权选项
这些语句创建了一个管理
可以管理所有的用户授权代理
映射。例如,管理
可以这样做:
格兰特代理莎莉给乔;
要指定一些或所有用户应该使用给定的身份验证插件连接,请创建一个”空白”MySQL帐户,用户名和主机名为空(“@”
),将其与该插件关联,并让插件返回真实的经过身份验证的用户名(如果与空白用户名不同)。假设存在一个名为a ldap_auth
它实现LDAP身份验证,并将用户连接到开发人员或管理人员帐户。要设置用户代理到这些帐户,请使用以下语句:
create USER " @ " IDENTIFIED WITH ldap_auth AS 'O=Oracle, OU=MySQL';——创建代理账户;使用——mysql_no_login插件阻止直接登录CREATE USER 'manager'@'localhost' IDENTIFIED WITH mysql_no_login;授给代理帐户的代理权限将“developer”@“localhost”上的代理授权给“@”
现在假设客户端按如下方式连接:
$> mysql——user=myuser——password输入密码:myuser_password
服务器找不到myuser
定义为MySQL用户,但因为有一个空白的用户帐户(“@”
)匹配客户端用户名和主机名,服务器就根据该帐户对客户端进行身份验证。服务器调用a ldap_auth
身份验证插件和通行证myuser
而且myuser_password
作为用户名和密码。
如果a ldap_auth
插件在LDAP目录中找到myuser_password
不正确的密码myuser
,验证失败,服务器拒绝连接。
如果密码正确且a ldap_auth
发现,myuser
是开发者,它返回用户名吗开发人员
到MySQL服务器,而不是myuser
.返回与的客户端用户名不同的用户名myuser
向服务器发送它应该处理的信号myuser
作为一个代理。服务器进行验证“@”
可以验证开发人员
(因为“@”
有代理
特权这样做)并接受连接。会议继续myuser
有…特权的开发人员
代理用户。(这些特权应该由DBA使用格兰特
语句,没有显示)。的用户()
而且CURRENT_USER ()
函数返回以下值:
SELECT USER(), CURRENT_USER();+------------------+---------------------+ | 用户()| CURRENT_USER () | +------------------+---------------------+ | myuser@localhost | developer@localhost | +------------------+---------------------+
如果插件在LDAP目录中找到myuser
是经理,它还会回报吗经理
作为用户名和会话继续进行myuser
有…特权的经理
代理用户。
SELECT USER(), CURRENT_USER();+------------------+-------------------+ | 用户()| CURRENT_USER () | +------------------+-------------------+ | myuser@localhost | manager@localhost | +------------------+-------------------+
为简单起见,外部身份验证不能是多级的开发人员
也不是的经理
在前面的例子中都考虑到了。但是,如果客户端试图直接连接和身份验证开发人员
或经理
帐户,这就是为什么应该保护那些代理帐户不被直接登录(参见防止直接登录代理帐户).
如果您打算创建一个默认代理用户,请检查是否已有其他代理用户”匹配任何用户”优先于默认代理用户的帐户,因为它们可以阻止该用户按预期工作。
在前面的讨论中,默认代理用户帐户有”
在主机部分中,它匹配任何主机。如果设置了默认代理用户,也要注意检查是否存在具有相同用户部分和的非代理帐户“%”
在宿主部分,因为“%”
也匹配任何主机,但具有优先级”
根据服务器用于在内部对帐户行进行排序的规则(参见第6.2.6节,“访问控制,第一阶段:连接验证”).
假设MySQL安装包含以下两个帐户:
——创建默认代理帐户create USER @ @ WITH some_plugin AS 'some_auth_string”;——创建匿名帐户创建用户“@ %”anon_user_password”;
第一个帐户(“@”
)被用作默认代理用户,用于验证那些在其他方面不匹配更特定帐户的用户的连接。第二个帐户(“@‘%’
)是一个匿名用户帐户,例如,创建该帐户可能是为了使没有自己帐户的用户能够匿名连接。
两个帐户具有相同的用户部分(”
),匹配任何用户。每个帐户都有一个与任何主机相匹配的主机部分。然而,在连接尝试的帐户匹配中有一个优先级,因为匹配规则对主机进行排序“%”
之前,”
.对于不匹配任何更特定的帐户的帐户,服务器将尝试对其进行身份验证“@‘%’
(匿名用户)而不是“@”
(默认代理用户)。因此,永远不会使用默认的代理帐户。
为了避免这个问题,可以使用以下策略之一:
删除匿名帐户,使其与默认代理用户不冲突。
使用在匿名用户之前匹配的更特定的默认代理用户。例如,只允许
本地主机
代理连接,使用”@“localhost”
:CREATE USER " @'localhost' IDENTIFIED WITH some_plugin AS 'some_auth_string”;
此外,修改任何
授权代理
报表名称”@“localhost”
而不是“@”
作为代理用户。请注意,此策略防止匿名用户连接
本地主机
.使用有名称的默认帐户,不要使用匿名的默认帐户。方法的使用说明提供了此技术的示例
authentication_windows
插件。看到第6.4.1.6节,“Windows可插入认证”.创建多个代理用户,一个用于本地连接,另一个用于”其他的一切”(远程连接)。这可能非常有用,特别是当本地用户应该拥有与远程用户不同的特权时。
创建代理用户:
create user " @ localhost' IDENTIFIED WITH some_plugin AS 'some_auth_string”;create user " @'%' WITH some_plugin AS 'some_auth_string”;
创建代理用户:
——创建本地连接的代理用户——创建远程连接的代理用户
授权给每个代理帐户
代理
对应代理帐户的权限:授权代理“开发者”@“本地主机”将“开发者”@“%”上的代理授权给“@“%”;
最后,向本地和远程代理用户授予适当的特权(没有显示)。
假设
some_plugin
/'
结合原因some_auth_string
'some_plugin
将客户端用户名映射到开发人员
.本地连接与”@“localhost”
代理用户,该用户映射到“开发人员”@“localhost”
代理用户。远程连接与“@‘%’
代理用户,该用户映射到“开发人员”@“%”
代理用户。
一些身份验证插件为自己实现代理用户映射(例如,PAM和Windows身份验证插件)。其他认证插件默认情况下不支持代理用户。其中,一些可以请求MySQL服务器自己映射代理用户根据授予的代理权限:mysql_native_password
,sha256_password
.如果check_proxy_users
系统变量被启用,服务器会对任何发出这样请求的认证插件执行代理用户映射:
默认情况下,
check_proxy_users
禁用,因此服务器不执行代理用户映射,即使对于请求服务器支持代理用户的身份验证插件也是如此。如果
check_proxy_users
,可能还需要启用特定于插件的系统变量,以利用服务器代理用户映射支持:为
mysql_native_password
插件,使mysql_native_password_proxy_users
.为
sha256_password
插件,使sha256_password_proxy_users
.
例如,要启用上述所有功能,请使用my.cnf
文件:
[mysqld] check_proxy_users=ON mysql_native_password_proxy_users=ON sha256_password_proxy_users=ON
假设已经启用了相关的系统变量,请像往常一样使用创建代理用户创建用户
,然后授予它代理
权限到要作为代理用户处理的单个其他帐户。当服务器收到代理用户的成功连接请求时,它发现该用户具有代理
特权,并使用它来确定适当的代理用户。
create USER 'proxy_user'@'localhost' IDENTIFIED WITH ' mysql_native_password '密码”;—创建代理帐户并授予其特权;CREATE USER 'proxied_user'@'localhost' IDENTIFIED WITH mysql_no_login;授予代理帐户权限grant…在…“proxied_user”@“localhost”;grant proxy ON ' proxyed_user '@'localhost' to 'proxy_user'@'localhost';
要使用代理帐户,请使用代理帐户的名称和密码连接服务器:
$> -u proxy_user -p输入密码:(此处输入proxy_user密码)
认证成功,服务器发现proxy_user
有代理
特权的proxied_user
,然后会话继续proxy_user
享有…的特权proxied_user
.
服务器执行的代理用户映射受以下限制:
服务器不会向匿名用户进行代理或从匿名用户进行代理,即使与
代理
好处是理所当然。当一个帐户被授予多个代理帐户的代理权限时,服务器代理用户映射是不确定的。因此,不建议向单个帐户授予多个代理帐户的代理权限。
两个系统变量有助于跟踪代理登录过程:
proxy_user
:该值为零
如果不使用代理。否则,表示代理用户帐号。例如,如果客户端通过“@”
代理帐户,该变量设置如下:mysql >选择@@proxy_user;+--------------+ | @@ proxy_user | +--------------+ | ''@'' | +--------------+
external_user
:有时认证插件可能使用外部用户对MySQL服务器进行认证。例如,当使用Windows本机身份验证时,使用Windows API进行身份验证的插件不需要传递给它的登录ID。但是,它仍然使用Windows用户ID进行身份验证。插件可以将这个外部用户ID(或它的前512 UTF-8字节)返回给服务器external_user
只读会话变量。如果插件没有设置此变量,则其值为零
.