mysql存儲過程的definer和invoker

【存儲過程的權限】mysql

ALTER ROUTINE 編輯或刪除存儲過程sql

CREATE ROUTINE 建立存儲過程數據庫

EXECUTE運行存儲過程安全


【存儲過程的建立語法】函數

delimiter //    -- 聲明分隔符(命令結束符)this

create ci

 definer = user@hostname | current_user it

 procedure 存儲過程名 (參數)io

 comment '註釋'ast

 sql security definer | invoker   -- sql 的安全設置

begin

  存儲過程的body

end

//

delimiter ;    -- 聲明分隔符(命令結束符)


【函數的建立語句】

delimiter //    -- 聲明分隔符(命令結束符)

create

 definer = user@hostname | current_user

 function 函數名(參數)

 return 返回值類型

 comment '註釋'

 sql security definer | invoker   -- sql 的安全設置

begin

  函數的body

end


//

delimiter ;    -- 聲明分隔符(命令結束符)


【definer和invoker的解釋】

    建立存儲過程的時候能夠指定 SQL SECURITY屬性,設置爲 DEFINER 或者INVOKER,用來奉告mysql在執行存儲過程的時候,,是以DEFINER用戶的權限來執行,仍是以調用者的權限來執行。

   默認狀況下,使用DEFINER方式,此時調用存儲過程的用戶必須有存儲過程的EXECUTE權限,而且DEFINER指定的用戶必須是在mysql.user表中存在的用戶。

   DEFINER模式下,默認DEFINER=CURRENT_USER,在存儲過程執行時,mysql會檢查DEFINER定義的用戶'user_name'@'host_name'的權限;

   INVOKER模式下,在存儲過程執行時,會檢查存儲過程調用者的權限。


  案例一:DEFINER

   CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()

   BEGIN

       SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;

   END;

   在這個案例中,不論哪一個用戶A調用存儲過程,存儲過程都會以'admin'@'localhost'的權限去執行,即便這個用戶A沒有查詢mysql.user表的權限。


 案例二:INVOKER

   CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()

       SQL SECURITY INVOKER

   BEGIN

       SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;

   END;

   在這個案例中,雖然存儲過程語句中仍然帶有DEFINER參數,可是因爲SQL SECURITY指定了INVOKER,因此在存儲過程執行的時候,會以調用者的額身份去執行。此時這個存儲過程是否能成功執行,取決於調用者是否有mysql.user表的查詢權限。


【案例】

案例一:調用存儲過程

 存儲過程的調用者是 : admin@192.168.1.1

 存儲過程的DEFINER是   : admin@%

 MySQL中存在的用戶是 : admin@192.168.%.%


   此時admin@192.168.1.1是能夠訪問數據庫的,由於它符合admin@192.168.%.%的受權規則,可是當它調用DEFINER='admin@%'的存儲過程的時候,mysql會檢查mysql.user用戶表中是否存在admin@%這個用戶,mysql的檢查結果是admin@%這個用戶不存在,此時就會返回報錯,提示「Ther user specified as a definer ('admin@%') does not exist.。

 

案例二:建立存儲過程


 使用用戶admin@192.168.1.1鏈接mysql,該用戶有test庫的all privileges,執行建立存儲過程的操做:

         存儲過程當中定義的DEFINER是   : admin@%

         MySQL中存在的用戶是 : admin@192.168.%.%

 此時,會遇到報錯,提示」ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation「

 修復DEFINER='admin@192.168.%.%',或者去掉 DEFINER參數,均可以恢復正常。


說明:

   案例一中是存在問題的,存儲過程的調用者和擁有者都是admin@192.168.1.1,可是DEFINER倒是admin@%,這是因爲建立存儲過程的命令是由root用戶執行的,因此沒有遇到案例二中的報錯。


【存儲過程經常使用命令】


查看存儲過程的建立語句:

show create procedure 存儲過程名;

查看存儲過程的信息:

show procedure status like '存儲過程名'G

查看存儲過程的Definer信息:

select db,name,type,sql_security,definer from mysql.proc where  type='PROCEDURE' and db='數據庫名' ;

修改存儲過程的DEFINER:

update  mysql.proc  set `definer` ='admin@192.168.%.%' where db like 'db_%';

相關文章
相關標籤/搜索