Applications can use the following guidelines to perform SQL-based auditing that ties database activity to MySQL accounts.应用程序可以使用以下准则来执行基于SQL的审计,将数据库活动与MySQL帐户联系起来。
MySQL accounts correspond to rows in the MySQL帐户对应于mysql.user
system table. When a client connects successfully, the server authenticates the client to a particular row in this table. mysql.user
系统表中的行。当客户端成功连接时,服务器会将客户端身份验证到此表中的特定行。The 此行中的User
and Host
column values in this row uniquely identify the account and correspond to the '
format in which account names are written in SQL statements.user_name
'@'host_name
'User
和Host
列值唯一标识帐户,并对应于SQL语句中写入帐户名的'user_name'@'host_name'
格式。
The account used to authenticate a client determines which privileges the client has. 用于验证客户端的帐户决定了客户端具有哪些权限。Normally, the 通常,可以调用CURRENT_USER()
function can be invoked to determine which account this is for the client user. CURRENT_USER()
函数来确定这是客户端用户的哪个帐户。Its value is constructed from the 其值由帐户的用户表行的User
and Host
columns of the user
table row for the account.User
和Host
列构成。
However, there are circumstances under which the 但是,在某些情况下,CURRENT_USER()
value corresponds not to the client user but to a different account. This occurs in contexts when privilege checking is not based the client's account:CURRENT_USER()
值不是对应于客户端用户,而是对应于不同的帐户。这发生在特权检查不基于客户端帐户的情况下:
Stored routines (procedures and functions) defined with the 用SQL SECURITY DEFINER
characteristicSQL SECURITY DEFINER
特性定义的存储例程(过程和函数)
Views defined with the 使用SQL SECURITY DEFINER
characteristicSQL SECURITY DEFINER
特性定义的视图
Triggers and events触发器和事件
In those contexts, privilege checking is done against the 在这些情况下,权限检查是针对DEFINER
account and CURRENT_USER()
refers to that account, not to the account for the client who invoked the stored routine or view or who caused the trigger to activate. DEFINER
帐户进行的,CURRENT_USER()
引用该帐户,而不是调用存储例程或视图或激活触发器的客户端的帐户。To determine the invoking user, you can call the 要确定调用用户,可以调用USER()
function, which returns a value indicating the actual user name provided by the client and the host from which the client connected. USER()
函数,该函数返回一个值,指示客户端提供的实际用户名和客户端连接的主机。However, this value does not necessarily correspond directly to an account in the 但是,此值不一定直接对应于user
table, because the USER()
value never contains wildcards, whereas account values (as returned by CURRENT_USER()
) may contain user name and host name wildcards.user
表中的帐户,因为USER()
值从不包含通配符,而帐户值(由CURRENT_USER()
返回)可能包含用户名和主机名通配符。
For example, a blank user name matches any user, so an account of 例如,空白用户名与任何用户匹配,因此''@'localhost'
enables clients to connect as an anonymous user from the local host with any user name. ''@'localhost'
帐户使客户端能够以匿名用户的身份从本地主机以任何用户名连接。In this case, if a client connects as 在这种情况下,如果客户端从本地主机以user1
from the local host, USER()
and CURRENT_USER()
return different values:user1
身份连接,则USER()
和CURRENT_USER()
返回不同的值:
mysql> SELECT USER(), CURRENT_USER();
+-----------------+----------------+
| USER() | CURRENT_USER() |
+-----------------+----------------+
| user1@localhost | @localhost |
+-----------------+----------------+
The host name part of an account can also contain wildcards. 帐户的主机名部分也可以包含通配符。If the host name contains a 如果主机名包含'%'
or '_'
pattern character or uses netmask notation, the account can be used for clients connecting from multiple hosts and the CURRENT_USER()
value does not indicate which one. '%'
或'_'
模式字符或使用网络掩码表示法,则该帐户可用于从多个主机连接的客户端,并且CURRENT_USER()
值不指示哪个主机。For example, the account 例如,'user2'@'%.example.com'
can be used by user2
to connect from any host in the example.com
domain. user2
可以使用帐户'user2'@'%.example.com'
从example.com
域中的任何主机进行连接。If 如果user2
connects from remote.example.com
, USER()
and CURRENT_USER()
return different values:user2
从remote.example.com
连接,则USER()
和CURRENT_USER()
返回不同的值:
mysql> SELECT USER(), CURRENT_USER();
+--------------------------+---------------------+
| USER() | CURRENT_USER() |
+--------------------------+---------------------+
| user2@remote.example.com | user2@%.example.com |
+--------------------------+---------------------+
If an application must invoke 如果应用程序必须调用USER()
for user auditing (for example, if it does auditing from within triggers) but must also be able to associate the USER()
value with an account in the user
table, it is necessary to avoid accounts that contain wildcards in the User
or Host
column. USER()
进行用户审核(例如,如果它从触发器内进行审核),但还必须能够将USER()
值与user
表中的帐户相关联,则有必要避免在User
或Host
列中包含通配符的帐户。Specifically, do not permit 具体来说,不允许User
to be empty (which creates an anonymous-user account), and do not permit pattern characters or netmask notation in Host
values. User
为空(这会创建匿名用户帐户),也不允许在Host
值中使用模式字符或网络掩码表示法。All accounts must have a nonempty 所有帐户必须具有非空的User
value and literal Host
value.User
值和文字Host
值。
With respect to the previous examples, the 关于前面的示例,应将''@'localhost'
and 'user2'@'%.example.com'
accounts should be changed not to use wildcards:''@'localhost'
和'user2'@'%.example.com'
帐户更改为不使用通配符:
RENAME USER ''@'localhost' TO 'user1'@'localhost'; RENAME USER 'user2'@'%.example.com' TO 'user2'@'remote.example.com';
If 如果user2
must be able to connect from several hosts in the example.com
domain, there should be a separate account for each host.user2
必须能够从example.com
域中的多个主机连接,则每个主机都应该有一个单独的帐户。
To extract the user name or host name part from a 要从CURRENT_USER()
or USER()
value, use the SUBSTRING_INDEX()
function:CURRENT_USER()
或USER()
值中提取用户名或主机名部分,请使用SUBSTRING_INDEX()
函数:
mysql>SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',1);
+---------------------------------------+ | SUBSTRING_INDEX(CURRENT_USER(),'@',1) | +---------------------------------------+ | user1 | +---------------------------------------+ mysql>SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',-1);
+----------------------------------------+ | SUBSTRING_INDEX(CURRENT_USER(),'@',-1) | +----------------------------------------+ | localhost | +----------------------------------------+