扩展MySQL 5.6/....../ 在身份验证插件中实现代理用户支持

4.4.9.4在认证插件中实现代理用户支持

可插入身份验证的功能之一是代理用户(参见代理用户)。服务器端认证插件要参与代理用户支持,必须满足以下条件:

  • 当连接的客户端应该被当作代理用户时,插件必须在验证_as.的成员mysql_server_auth_info.结构,表示代理的用户名。也可以选择设置External_User.属性的值External_User.系统变量。

  • 代理用户帐户必须被设置为通过插件的身份验证。使用创建用户授予语句将帐户与插件关联。

  • 代理用户帐户必须具有代理人代理帐户的特权。使用授予授予此特权的声明。

换句话说,插件所需的代理用户支持的唯一方面是它设置验证_as.到代理的用户名。其余的是可选的(设置External_User.)或者由DBA使用SQL语句完成。

当代理用户连接时,身份验证插件如何确定返回哪个代理用户?这取决于插件。通常,插件根据服务器传递给它的身份验证字符串将客户端映射到代理用户。这个字符串来自作为的一部分确定条款的创建用户语句指定插件用于身份验证的使用。

Plugin Developer确定身份验证字符串的语法规则,并根据这些规则实现插件。假设插件采用将外部用户映射到MySQL用户的逗号分隔的对列表。例如:

CREATE USER " @'%.example.org' IDENTIFIED WITH my_plugin AS 'extuser1=mysqluserc, extuser2=mysqluserd'

当服务器调用插件以验证客户端时,它将相应的身份验证字符串传递给插件。插件负责:

  1. 将字符串解析为其组件,以确定要使用的映射

  2. 将客户端用户名与映射进行比较

  3. 返回正确的mysql用户名

例如,如果Extuser2.连接从一个example.com.主机,服务器通过'extuser1 = mysqlusera,extuser2 = mysqluserb'到插件,插件应该复制mysqluserb.进入验证_as.,以空字节结束。如果Extuser2.连接从一个example.org.主机,服务器通过'extuser1 = mysqluserc,extuser2 = mysqluserd',插件应该复制mysqluserd.反而。

如果映射中没有匹配项,则操作取决于插件。如果需要匹配,插件很可能会返回一个错误。或者插件可以简单地返回客户端名称;在这种情况下,它不应该改变验证_as.,服务器不会将客户端视为代理。

以下示例演示了如何使用名为的插件处理代理用户auth_simple_proxy.。如auth_simple.插件前面所描述的,auth_simple_proxy.接受任何非空密码,如有效(因此不应在生产环境中使用)。另外,它检查了auth_string.身份验证字符串成员,并使用这些非常简单的规则来解释它:

  • 如果字符串为空,则插件将返回给定的用户名,不会发生代理。也就是说,插件离开了价值验证_as.不变。

  • 如果字符串是非空的,插件将其作为被代理用户的名称并复制到验证_as.这样代理就发生了。

用于测试,设置根据前述规则的一个未代理的帐户,以及其中一个帐户。这意味着一个帐户没有作为条款,其中包括作为子句姓名代理用户:

使用auth_simple_proxy创建用户'plugin_user1'@'localhost';使用auth_simple_proxy创建用户'plugin_user2'@'localhost'作为'proxied_user';

此外,为代理用户和授予创建一个帐户plugin_user2代理人特权:

CREATE USER 'proxied_user'@'localhost' IDENTIFIED BY 'proxied_user_pass';GRANT PROXY ON 'proxied_user'@'localhost' TO 'plugin_user2'@'localhost';

在服务器调用身份验证插件之前,它会设置验证_as.到客户端用户名。要指示用户是代理,请将插件设置为验证_as.到代理的用户名。为了auth_simple_proxy.,这意味着它必须检查auth_string.值,并且,如果值是非空的,请将其复制到验证_as.成员将其作为代理用户的名称返回。此外,当代理发生时,插件设置External_User.成员到客户端用户名;这就变成了External_User.系统变量。

static int auth_simple_proxy_server(mysql_plugin_vio * vio,mysql_server_auth_info * info){unsigned char * pkt;int pkt_len;/ *将密码读取为null终止字符串,错误* / if((pkt_len = vio-> read_packet(vio,&pkt))<0)返回cr_error;/ *在空密码* / if(!pkt_len || * pkt =='\ 0'){info-> password_used = password_used_no;返回cr_error;} / *接受任何非空的密码* / info-> password_used = password_used_yes;/ *如果身份验证字符串是非空的,请用作代理用户名* / / *,并使用客户名称作为External_User值* / if(信息 - > auth_string_length> 0){strcpy(info-> authoricated_as,info-> auth_string);strcpy(Info-> External_User,Info-> User_Name);}返回cr_ok;}

成功连接后,用户()函数应该指示连接的客户端用户和主机名,以及CURRENT_USER ()应指明在会议期间适用的帐户。如果未发生代理,后者值应为连接用户帐户,如果发生代理,则代理帐户。

编译并安装插件,然后测试它。首先,连接plugin_user1

shell> mysql——user=plugin_user1——password输入密码:x

在这种情况下,应该没有代理:

mysql> select user(),current_user(),@@ proxy_user,@@ener_user \ g *************************** 1.行***************************用户():plugin_user1 @ localhost current_user():plugin_user1 @ localhost @@ proxy_user:null @@ extent_user:空值

然后连接plugin_user2

shell> mysql——user=plugin_user2——password输入密码:x

在这种情况下,plugin_user2应该被提到proxied_user.

mysql> select user(),current_user(),@@ proxy_user,@@ener_user \ g *************************** 1.行***************************用户():plugin_user2 @ localhost current_user():proxied_user @ localhoster @@ proxy_user:'plugin_user2'@'localhost'@@ hyperence_user:'plugin_user2'@'localhost'