博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Oracle所有者权限与调用者权限
阅读量:5154 次
发布时间:2019-06-13

本文共 8361 字,大约阅读时间需要 27 分钟。

在Oracle中,系统权限、对象权限以及他们的集合角色权限,是一个相对复杂的安全体系。在前一篇《使用Role权限体系》()中,已经进行初步介绍。存储过程作为Schema对象下的程序单元,在进行Role处理时有一些特殊之处。今天我们继续介绍存储过程的权限体系:和。

在存储过程中,我们常常面对这样一个场景:用户A下有一个存储过程(或者函数体、包体)P,中间引用了对象X。在编译存储过程时,是要求用户A有对象X的权限的,如果没有,则系统报编译错误。当成功进行编译之后,用户A将执行execute存储过程P的权限赋给了用户B。但是用户B这时候不一定拥有X的使用权限,此时B能够成功执行存储过程P呢?我们通过一个简单,来证实一下。

实验环境准备

先准备用户test,除了具备基本的connect和resource角色权限之外,处于实验目的,赋给select any dictionary的系统权限给test。

SQL> conn sys/sys@otstest as sysdba;Connected to Oracle Database 10g EnterpriseEdition Release10.2.0.1.0Connected as SYSSQL>SQL> create user test 2   identified by test;User createdSQL> grant resource to test;Grant succeeded SQL> grant connect to test;Grant succeededSQL> grant select any dictionary to test;Grant succeeded

Select any dictionary的系统权限意味着用户可以访问数据字典视图层面的视图对象数据,而且不会因为存储过程对角色权限的剥离效应而受到影响。

SQL> conn test/test @otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as testSQL> select count(*) fromdba_objects; COUNT(*)-------------- 53305SQL> 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 /Procedure createdSQL> set serveroutput on size 1000;SQL> exec p_test_nc;53306PL/SQL procedure successfully completed

可见,授予select any dictionary的用户test可以对dba_objects视图进行访问操作。同时,存储过程p_test_nc也可以顺利的编译执行。

实验一 —— 所有者权限

准备好的实验环境,我们准备进行第一个项目实验。建立一个新用户ts,只有执行test用户下p_test_nc存储过程权限,但是没有访问dba_objects视图权限,看实际效果。

SQL> conn sys/sys@otstest as sysdba;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as SYSSQL> create user ts 2   identified by ts;User createdSQL> grant resource to ts;Grant succeededSQL> grant connect to ts;Grant succeeded//用户ts只具有基本的连接和创建对象权限。SQL> conn test/test@otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as test//将p_test_nc执行权限授权给tsSQL> grant execute on p_test_nc to ts;Grant succeeded

之后,我们检查ts用户下,p_test_nc的执行情况。

SQL> conn ts/ts@otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as ts SQL> select count(*) from dba_objects; select count(*) from dba_objects//ts用户没有dba_objects权限,显示访问必然没有结果;ORA-00942:表或视图不存在SQL> set serveroutput on size 1000;SQL> exec test.p_test_nc;53306PL/SQL procedure successfully completed

结果显而易见,ts虽然没有访问dba_objects权限,但是因为拥有执行p_test_nc的权限,在执行p_test_nc的时候,也是可以在方法中访问到dba_objects。显然,此时ts在p_test_nc上借用了test用户对于dba_objects用户的权限,也就是对象所有者权限。

进一步证明我们的实验,可以进行些变化。

--当所有者权限失去时,即使调用者拥有权限也是无用的。

SQL> conn sys/sys@otstest as sysdba;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as SYS//回收了test用户上的select any dictionary权限,此时test对dba_objects对象权限消失;SQL> revoke select any dictionary from test;Revoke succeeded//赋予ts用户select any dictionary权限,这样ts就能访问dba_objects了;SQL> grant select any dictionary to ts;Grant succeededSQL> conn ts/ts@otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as tsSQL> set serveroutput on size 1000;SQL> select count(*) from dba_objects;//可以访问对象 COUNT(*)----------    53306SQL> exec test.p_test_nc;begin test.p_test_nc; end;ORA-06550:第1行,第12列:PLS-00905:对象TEST.P_TEST_NC无效ORA-06550:第1行,第7列:PL/SQL: Statement ignored

我们看到了一些“诡异现象”,ts用户拥有dba_objects对象访问权限,同时也有执行p_test_nc的权限,但是执行的时候却报错,认为对象无效。

唯一的原因就是因为test用户失去了dba_objects对象的权限。而ts在调用p_test_nc时使用的是dba_objects的权限。

上面,我们就介绍了Oracle在存储过程中使用的权限配置“所有者权限”。简单的说,当执行一个程序体(存储过程、函数和包等)的时候,方法体内部使用的权限体系为当前该程序体所有者的权限体系,而与调用方法的用户无关。存储过程p_test_nc此时,无论是谁在执行,权限体系都是该存储过程的所有者test的权限。

所有者权限是Oracle使用的默认权限选择方式,在使用的时候很方便。使用者只要拥有简单的对象执行权限就可以了,无需顾及自己是否有权限访问方法中使用的对象。

 

 

有了前面对的介绍,的含义就相对容易理解了。调用者权限体系就是执行方法体的时候,使用的权限按照调用者权限体系来判断。一个方法的执行,调用者除了要拥有方法的执行权限,还要拥有方法中使用对象的权限才可以。

 

二——调用者权限

 

我们继续实验一的环境。注意,此时test用户没有select any dictionary权限,而ts拥有。

 

SQL> conn test/test@otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0 Connected as testSQL>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 Database10gEnterpriseEdition Release10.2.0.1.0Connected as SYSSQL> grant select any dictionary to test;Grant succeeded

切换回ts用户,注意此时他是拥有select any dictionary权限的。

SQL> conn ts/ts@otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as tsSQL> exec test.p_test_nc;PL/SQL procedure successfully completedSQL> set serveroutput on size 1000;SQL> exec test.p_test_nc;53306PL/SQL procedure successfully completedSQL> select count(*) from dba_objects; COUNT(*)----------------------    53306

此时,执行顺利成功。因为此时test和ts都拥有select any dictionary权限,所以即使在调用者权限下,也是会成功的。那么,如果我们收回ts上的权限,会如何呢?

 

SQL> conn sys/acca@otstest as sysdba;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as SYSSQL>revoke select any dictionary from ts; //权限回收Revoke succeededSQL> conn ts/ts@otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as tsSQL> 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 6ORA-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 Database10gEnterpriseEdition Release10.2.0.1.0Connected as SYSSQL> grant select_catalog_role to ts;Grant succeeded

对对象ts赋予select_catalog_role角色,该角色是能够访问dba_objects的,但是在所有者权限体系下,角色权限会被剔除。

SQL> conn ts/ts@otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as tsSQL> select count(*) from dba_objects; COUNT(*)--------------------  53306SQL> set serveroutput on size 1000;SQL> exec test.p_test_nc;53306PL/SQL procedure successfully completed

注意:我们发现,调用者权限p_test_nc方法应该使用调用者ts的权限。此时ts只有一个select_catalog_role角色权限与dba_objects有关联。可以猜想:在调用者方式下,非所有者调用时不会发生角色权限被剔除的现象。

SQL> conn sys/acca@otstest as sysdba; Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as SYSSQL> revoke select any dictionary from test;Revoke succeededSQL> grant select_catalog_role to test;Grant succeededSQL> conn test/test@otstest;Connected to Oracle Database10gEnterpriseEdition Release10.2.0.1.0Connected as testSQL> select count(*) from dba_objects; COUNT(*)--------------------------  53306SQL> 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,可以从调用者权限的角度去寻求解决方法;

 

转载于:https://www.cnblogs.com/Jace06/articles/7358686.html

你可能感兴趣的文章
CSS--字体
查看>>
vs调试技巧
查看>>
edmx文件
查看>>
限定符注解
查看>>
Linux环境下安装python3
查看>>
触摸隐藏键盘
查看>>
jstl foreach 取index
查看>>
div+CSS3实现制作精美漂亮的圆角按钮特效代码
查看>>
protobuf 安装与卸载
查看>>
jQuery基础——事件
查看>>
Java对象和引用
查看>>
ensp 启动路由器 43 错误解决方法
查看>>
Tail-chaining(末尾连锁)中断说明
查看>>
ASP.NET 推荐书籍
查看>>
mysql安装
查看>>
20172319 《程序设计与数据结构》 第二周学习总结
查看>>
02-Python基础之列表
查看>>
08-Python基础之迭代器与生成器
查看>>
POJ P3254 Corn fields 【状压dp】
查看>>
BZOJ3542 DZY Loves March 【map + 线段树】
查看>>