MySQL的视图、触发器、存储过程、存储函数定义中都会涉及definer参数及配套的SQL SECURITY
如存储过程定义:
CREATE [DEFINER = user] PROCEDURE [IF NOT EXISTS] sp_name ([proc_parameter[,...]])
SQL SECURITY { DEFINER | INVOKER }
BEGIN
<执行部分>
END;
一.作用及意义
DEFINER参数是用来限制调用者权限,默认SQL SECURITY 的值为 DEFINER,即表示调用者若想 CALL 此对象,必须DEFINER用户具备该对象的调用权限。SQL SECURITY 的值为 INVOKER时,DEFINER参数失效。
例如:存储过程proc_1涉及查询A、B两张表,定义者对A有查询权限,对B不存在查询权限,此时定义者将无法调用proc_1,其他具备A/B表查询权限的人,也无法调用proc_1。
二、示例说明SQL SECURITY DEFINER
调用者能成功调用存储过程的前提条件是:
1.本身具备调用该对象的权限;
2.该对象的定义者具有该对象的调用权限;
3.该对象的定义者具有访问该对象涉及的其他对象权限),如查询了其他表;
2.1 示例1:
库test
用户:root,DBA权限
用户:TEST01,仅具有test库的查询权限
用户:TEST02,仅具有test库的存储执行权限
-- root创建两个分别定义者为TEST01和TEST02的存储过程
DELIMITER &&
CREATE DEFINER=TEST01 PROCEDURE test.proc_1()
BEGIN
select * from test.EMPLOYEE;
END &&
DELIMITER &&
CREATE DEFINER=TEST02 PROCEDURE test.proc_2()
BEGIN
select * from test.EMPLOYEE;
END &&
结论:三用户无法调用这两个存储过程。
验证:给用户TEST02增加test.EMPLOYEE表的查询权限,则root、TEST02均可调用proc_2
GRANT SELECT on test.* TO TEST02;
三、示例说明SQL SECURITY INVOKER
调用者能成功调用存储过程的前提条件是:
1.本身具备调用该对象的权限;
2.本身具有访问该对象涉及的其他对象权限),如查询了其他表;
2.1 示例1
库test
用户:root,DBA权限
用户:TEST01,仅具有test库的查询权限
用户:TEST02,仅具有test库的存储执行权限
DELIMITER &&
CREATE DEFINER=TEST01 PROCEDURE test.proc_3()
SQL SECURITY INVOKER
BEGIN
select * from test.EMPLOYEE;
END &&
DELIMITER &&
CREATE DEFINER=TEST02 PROCEDURE test.proc_4()
SQL SECURITY INVOKER
BEGIN
select * from test.EMPLOYEE;
END &&
结论:只有root用户可以调用两个存储过程。