有了前面对所有者权限的介绍,调用者权限的含义就相对容易理解了。调用者权限体系就是执行方法体的时候,使用的权限按照调用者权限体系来判断。一个方法的执行,调用者除了要拥有方法的执行权限,还要拥有方法中使用对象的权限才可以。
实验二——调用者权限
我们继续实验一的环境。注意,此时test用户没有select any dictionary权限,而ts拥有。
SQL> conn test/test@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as test
SQL>
SQL> create or replace procedure p_test_nc
2 is
3 i number;
4 begin
5 select count(*)
6 into i
7 from dba_objects;
8
9 dbms_output.put_line(to_char(i));
10 end;
11 /
Warning: Procedure created with compilation errors
检查报错信息,还是因为没有dba_objects的权限。
SQL> select * from user_errors;
NAME TYPE SEQUENCE LINE POSITION TEXT
------------------------------- ---------- ---------- --------------------------------------
P_TEST_NC PROCEDURE 1 7 8 PL/SQL: ORA-00942: 表或视图不存在
P_TEST_NC PROCEDURE 2 5 3 PL/SQL: SQL Statement ignored
此时,我们如果在方法定义上加入authid current_user关键字,就可以将存储过程变化为调用者权限。
SQL> create or replace procedure p_test_nc
2 authid current_user
3 is
4 i number;
5 begin
6 select count(*)
7 into i
8 from dba_objects;
9
10 dbms_output.put_line(to_char(i));
11 end;
12 /
Warning: Procedure created with compilation errors
显然,还在因为dba_objects没有权限而报错,毕竟不管是什么体系,test目前是没有对象权限的。不过,为了实验成功,还是要让test能顺利编译过p_test_nc方法。
SQL> conn sys/acca@otstest as sysdba;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL> grant select any dictionary to test;
Grant succeeded
切换回ts用户,注意此时他是拥有select any dictionary权限的。
SQL> conn ts/ts@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as ts
SQL> exec test.p_test_nc;
PL/SQL procedure successfully completed
SQL> set serveroutput on size 1000;
SQL> exec test.p_test_nc;
53306
PL/SQL procedure successfully completed
SQL> select count(*) from dba_objects;
COUNT(*)
----------
53306
此时,执行顺利成功。因为此时test和ts都拥有select any dictionary权限,所以即使在调用者权限下,也是会成功的。那么,如果我们收回ts上的权限,会如何呢?
SQL> conn sys/acca@otstest as sysdba;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL> revoke select any dictionary from ts; //权限回收
Revoke succeeded
SQL> conn ts/ts@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as ts
SQL> select count(*) from otstest;
select count(*) from otstest
ORA-00942: 表或视图不存在
SQL> exec test.p_test_nc;
begin test.p_test_nc; end;
ORA-00942: 表或视图不存在
ORA-06512: 在 "TEST.P_TEST_NC", line 6
ORA-06512: 在 line 1
此时,就看出调用者权限的差异了。Test始终有dba_objects的权限,而ts在之后被取消了select any dictionary的权限。如果是所有者权限,ts调用p_test_nc是没有问题的。但是此时报错,说明此处使用的ts调用者权限。
调用者权限与role权限剥离现象
结合之前介绍的role权限剥离的现象,在调用者权限下,这种现象还有吗?我们下面的实验来证实。
继续上面实验的环境,用户ts已经失去了对dba_objects能访问的权限。Test用户拥有select any dictionary系统权限。方法p_test_nc调节为调用者权限。
--调用者权限与role剥离情况
SQL> conn sys/acca@otstest as sysdba;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL> grant select_catalog_role to ts;
Grant succeeded
对对象ts赋予select_catalog_role角色,该角色是能够访问dba_objects的,但是在所有者权限体系下,角色权限会被剔除。
SQL> conn ts/ts@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as ts
SQL> select count(*) from dba_objects;
COUNT(*)
----------
53306
SQL> set serveroutput on size 1000;
SQL> exec test.p_test_nc;
53306
PL/SQL procedure successfully completed
注意:我们发现,调用者权限p_test_nc方法应该使用调用者ts的权限。此时ts只有一个select_catalog_role角色权限与dba_objects有关联。可以猜想:在调用者方式下,非所有者调用时不会发生角色权限被剔除的现象。
SQL> conn sys/acca@otstest as sysdba;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL> revoke select any dictionary from test;
Revoke succeeded
SQL> grant select_catalog_role to test;
Grant succeeded
SQL> conn test/test@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as test
SQL> select count(*) from dba_objects;
COUNT(*)
----------
53306
SQL> set serveroutput on size 10000;
SQL> exec p_test_nc;
begin p_test_nc; end;
ORA-06550: 第 1 行, 第 7 列:
PLS-00905: 对象 TEST.P_TEST_NC 无效
ORA-06550: 第 1 行, 第 7 列:
PL/SQL: Statement ignored
但是对于p_test_nc方法的所有者test来说,调用权限并没有解决role权限剔除的问题。依然存在存储过程角色剔除问题。
SQL> select * from dba_role_privs where grantee in ('TS','TEST');
GRANTEE GRANTED_ROLE
------------------------------ -----------------------
TEST RESOURCE
TS CONNECT
TEST SELECT_CATALOG_ROLE
TS SELECT_CATALOG_ROLE
TEST CONNECT
TS RESOURCE
6 rows selected
通过上述的实验,我们可以得到如下的经验:
ü 所有者权限和调用者权限是Oracle对存储过程等代码结构提供的独特权限组织模式。二者互为补充,应对不同的需求状况;
ü 即使在调用者模式下,可以一定程度的避免role剔除现象,我们还是不建议使用role权限管理用户;
ü 调用者权限体系在Oracle预定义方法、过程中大量采用,在进行开发的时候,如果遇到类似的问题和Bug,可以从调用者权限的角度去寻求解决方法;
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-692247/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/17203031/viewspace-692247/