问题描述
一直认为调用者权限过程所参考的对象是调用者用户下的对象,所依赖的权限也是调用者拥有的权限,但是现在发现事实并非完全如此。
专家解答
事实上这个观点对于表、视图是正确的,调用者权限存储过程访问的表和视图是调用者当前用户下的,且权限都来自调用者本身。
但是对于存储过程,却是个例外,调用者权限存储过程中调用的OWNER用户下的存储过程,对于调用者而言,即使没有权限也是可以访问的。
描述有点抽象,看一个简单的例子:
SQL> CONN SYSTEM/MANAGER 已连接。 SQL> CREATE USER U1 IDENTIFIED BY U1 DEFAULT TABLESPACE USERS; 用户已创建。 SQL> GRANT CREATE SESSION TO U1; 授权成功。 SQL> CONN TEST/TEST 已连接。 SQL> CREATE OR REPLACE PROCEDURE P_1 AUTHID CURRENT_USER AS 2 BEGIN 3 NULL; 4 END; 5 / 过程已创建。 SQL> CREATE OR REPLACE PROCEDURE P_2 AUTHID CURRENT_USER AS 2 BEGIN 3 P_1; 4 END; 5 / 过程已创建。 SQL> GRANT EXECUTE ON P_2 TO U1; 授权成功。 SQL> CONN U1/U1 已连接。 SQL> EXEC TEST.P_1 BEGIN TEST.P_1; END; * 第 1 行出现错误: ORA-06550: 第 1 行, 第 7 列: PLS-00201: 必须声明标识符 'TEST.P_1' ORA-06550: 第 1 行, 第 7 列: PL/SQL: Statement ignored SQL> EXEC TEST.P_2 PL/SQL 过程已成功完成。
创建一个只有CREATE SESSION权限的用户。在另外一个用户下,创建两个调用者权限的存储过程,其中P_2调用P_1。将存储过程P_2的执行权限授权给P_1。用新创建的用户登录,可以看到,用户没有权限执行P_1,但是用户可以执行P_2,这意味着用户通过P_2的执行权限,调用了存储过程OWNER用户下调用者本没有权限的存储过程P_1。
这对于定义者权限存储过程是顺理成章的,但是对于调用者存储过程而言,对象的访问权限是在调用时判断,因此由调用者确定访问的对象和权限。没有想到,Oracle这里的对象的范围并不包含存储过程。
第一个过程是否是调用者权限并不重要,将其改为定义者权限,结果依旧:
SQL> CONN TEST/TEST 已连接。 SQL> CREATE OR REPLACE PROCEDURE P_1 AS 2 BEGIN 3 NULL; 4 END; 5 / 过程已创建。 SQL> CREATE OR REPLACE PROCEDURE P_2 AUTHID CURRENT_USER AS 2 BEGIN 3 P_1; 4 END; 5 / 过程已创建。 SQL> CONN U1/U1 已连接。 SQL> EXEC TEST.P_2 PL/SQL 过程已成功完成。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。