oracle赋予用户创建方法的权限(oracle赋予用户调用某个过程权限)

技术Oracle中定义者权限和调用者权限的示例分析这篇文章给大家分享的是有关Oracle中定义者权限和调用者权限的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。定义者权限:定义者权限指

本文将与您分享Oracle中定义者权限和调用者权限的示例分析的内容。我觉得边肖很实用,就和大家分享一下作为参考。让我们跟着边肖看一看。

定义者权限:定义者权限是指使用其所有者的权限而不是当前用户的权限来执行流程。因此,您可以限制用户可以执行的数据库操作,并且只允许他们通过运行定义者授权的过程和函数来访问数据。创建过程、函数和包的默认权限是定义者权限。

调用者权限:在当前用户模式下以当前用户权限执行该过程。换句话说,调用者的权限过程并不依赖于特定的用户或模式。调用者的权限程序可以使应用程序开发人员很容易集中应用程序逻辑,即使底层数据在用户和模式之间划分。创建时需要显式使用AUTHID。

定义调用者过程。

(注意:在阅读下面案例的时候注意sqlplus的使用的不同用户)

演示如下:

1.创建两个测试用户wjq1和wjq2,并分别对他们进行授权。

SYS @ seiang11gcreate创建用户wjq1

由wjq1默认表空间seiang标识;

用户已创建。

SYS @ seiang11gcreate创建用户wjq2

由wjq2默认表空间seiang标识;

用户已创建。

SYS@seiang11ggrant

连接,资源到wjq1,wjq2

格兰特成功了。

2.切换到用户wjq1,创建两个过程,proc_definer和proc_invoker。

过程1:定义者权限,为创建过程的默认权限

WJQ1 @ seiang11gcreate创建或替换

过程定义器是

2 begin

3 DBMS _ output . put _ line(' Current user : ' | |)

sys_context('userenv ',' current _ user ');

4 DBMS _ output . put _ line(' Session user : ' | |)

sys_context('userenv ',' session _ user ');

5 DBMS _ output . put _ line(' Current Schema : ' | |)

sys_context('userenv ',' current _ schema ');

6 end proc_definer;

7 /

已创建过程。

过程2:使用使用者权限

WJQ1 @ seiang11gcreate创建或替换

过程proc_invoker authid

当前用户是

2 begin

3 DBMS _ output . put _ line(' Current user : ' | |)

sys_context('userenv ',' current _ user ');

4 DBMS _ output . put _ line(' Session user : ' | |)

sys_context('userenv ',' session_user

#39;));

  5     dbms_output.put_line('Current Schema:'||
sys_context('userenv','current_schema'));

  6  end proc_invoker;

  7  /

Procedure created.

3、查看两个过程的权限

WJQ1@seiang11g>select
object_name,procedure_name,authid from user_procedures

  2  where object_name like '%PROC%';

OBJECT_NAME                    PROCEDURE_NAME                 AUTHID

------------------------------
------------------------------ ------------

PROC_INVOKER                                                 
CURRENT_USER

PROC_DEFINER                                                 
DEFINER

4、在用户wjq1下分别执行定义者权限和使用者权限的过程

WJQ1@seiang11g>set serveroutput on

WJQ1@seiang11g>

WJQ1@seiang11g>exec proc_definer;

Current
User:WJQ1

Session
User:WJQ1

Current
Schema:WJQ1

PL/SQL procedure successfully
completed.

WJQ1@seiang11g>exec proc_invoker;

Current
User:WJQ1

Session
User:WJQ1

Current
Schema:WJQ1

PL/SQL procedure successfully
completed.

5、将用户wjq1创建的两个过程授权给用户wjq2

WJQ1@seiang11g>grant execute on
proc_definer to wjq2;

Grant succeeded.

WJQ1@seiang11g>grant execute on
proc_invoker to wjq2;

Grant succeeded.

6、在用户wjq2下分别调用两个过程,结果显示在调用者权限下,程序在当前用户下用当前用户的权限执行

WJQ2@seiang11g>set serveroutput on

WJQ2@seiang11g>exec
wjq1.proc_definer;

Current
User:WJQ1

Session
User:WJQ2

Current
Schema:WJQ1

PL/SQL procedure successfully
completed.

WJQ2@seiang11g>exec
wjq1.proc_invoker;

Current
User:WJQ2

Session
User:WJQ2

Current
Schema:WJQ2

PL/SQL procedure successfully
completed.

通过上面的简单的演示,已经对定义者权限和调用者权限有了一定的认识和理解,但是仅仅初步的了解在生产环境中,遇到实际的案例还是有点摸不着头脑,下面通过两个实际的案例来分析定义者权限和调用者权限,更加深入的去理解它们的使用方法。

在存储过程中,时常会遇到这样一种场景:用户A下有一个存储过程(或者函数体、包体)Proc,在过程中间引用了对象obj。在编译存储过程时,是要求用户A有对象obj的权限的,如果没有,则系统报编译错误。当成功进行编译之后,用户A将执行execute存储过程Proc的权限赋给了用户B。但是用户B不一定拥有对象obj的使用权限,那么问题就来了,此时用户B能否成功执行存储过程Proc呢?

下面我们通过实验来进行验证:

接着上面例子,用户wjq1和wjq2除了拥有connect和resource角色的权限之外,出于实验的目的,我们将select any
dictionary的系统权限赋予给用户wjq1

SYS@seiang11g>grant select any
dictionary to wjq1;

Grant succeeded.

select any
dictionary的系统权限意味着用户可以访问数据字典视图层面的视图中的对象数据。

WJQ1@seiang11g>select count(*)
from dba_objects;

 
COUNT(*)

----------

    
86993

WJQ1@seiang11g>create or replace
procedure proc_wjq1 is

  2  i number;

  3  begin

  4     select count(*) into i from dba_objects;

  5     dbms_output.put_line(to_char(i));

  6  end;

  7  /

Procedure created.

WJQ1@seiang11g>set serveroutput on

WJQ1@seiang11g>

WJQ1@seiang11g>exec proc_wjq1;

86994

PL/SQL procedure successfully
completed. 

由上可见:授予select
any dictionary的用户wjq1可以对dba_objects视图进行访问操作。同时,存储过程proc_wjq1也可以执行编译操作。

案例一:定义者权限

紧接着上面的实验,对于wjq2用户,只有执行wjq1用户下proc_wjq1存储过程权限,但是没有访问dba_objects视图权限,看实际效果。

用户wjq2只具有基本的connect和resource权限。将proc_wjq1过程的执行权限授权给wjq2

WJQ1@seiang11g>grant execute on
proc_wjq1 to wjq2;

Grant succeeded. 

之后,检查wjq2用户下,过程proc_wjq1的执行情况

WJQ2@seiang11g>select count(*)
from dba_objects;

select count(*) from dba_objects

                     *

ERROR at line 1:

ORA-00942: table or view does not exist

wjq2用户没有dba_objects权限,显示访问必然报错

WJQ2@seiang11g>exec
wjq1.proc_wjq1;

86994

PL/SQL procedure successfully
completed.

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

为了进一步证明结果的准确性,下面将继续进行实验变化来演示

当定义者权限失去时,即使调用者拥有权限也是无用的(也就是说wjq1用户没有访问dba_objects的权限,wjq2用户有访问dba_objects的权限)

回收了wjq1用户上的select
any dictionary权限,此时wjq1对dba_objects对象权限消失;然后,赋予wjq2用户select
any dictionary权限,这样wjq2就能访问dba_objects了

SYS@seiang11g>revoke select any
dictionary from wjq1;

Revoke succeeded.

WJQ1@seiang11g>select count(*)
from dba_objects;

select count(*) from dba_objects

                     *

ERROR at line 1:

ORA-00942:
table or view does not exist

SYS@seiang11g>

SYS@seiang11g>grant select any
dictionary to wjq2;

Grant succeeded.

WJQ2@seiang11g>select count(*)
from dba_objects;

 
COUNT(*)

----------

    
86994

WJQ2@seiang11g>exec
wjq1.proc_wjq1;

BEGIN wjq1.proc_wjq1; END;

           *

ERROR at line 1:

ORA-06550: line 1, column 12:

PLS-00905: object WJQ1.PROC_WJQ1 is invalid

ORA-06550: line 1, column 7:

PL/SQL: Statement ignored

通过上面的实验结果发现:wjq2用户拥有dba_objects对象访问权限,同时也有执行proc_wjq1的权限,但是执行的时候却报错,认为对象无效。这是为什么呢?唯一的原因就是因为wjq1用户失去了dba_objects对象的权限,而wjq2在调用proc_wjq1时使用的是dba_objects的权限。

以上案例一的实验介绍了Oracle在存储过程中使用的权限配置的“定义者权限”。简单的说,当执行一个程序体(存储过程、函数和包等)的时候,方法体内部使用的权限体系为当前该程序体定义者的权限体系,而与调用方法的用户无关。存储过程proc_wjq1无论是哪一个用户执行,权限体系都是该存储过程的定义者wjq1的权限。

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

案例一对定义者权限通过实验进行了分析,调用者权限的含义就相对容易理解了。调用者权限体系就是执行方法体的时候,使用的权限按照调用者权限体系来判断。一个方法的执行,调用者除了要拥有执行该方法的权限,还要拥有该方法中使用对象的权限才可以。

 

下面案例二通过实验对调用者权限作出详细的分析:

案例二:调用者权限

接着上面案例一的实验环境。注意,此时wjq1用户没有select
any dictionary权限,而wjq2有。

WJQ1@seiang11g>create or replace
procedure proc_wjq1_1 is

  2  i number;

  3  begin

  4     select count(*) into i from dba_objects;

  5     dbms_output.put_line(to_char(i));

  6  end;

  7  /

Warning: Procedure created
with compilation errors.

WJQ1@seiang11g>

WJQ1@seiang11g>select
name,line,text from user_errors;

NAME                  LINE TEXT

--------------- ----------
--------------------------------------------------

PROC_WJQ1_1              4
PL/SQL: ORA-00942: table or view does not exist

PROC_WJQ1_1              4 PL/SQL: SQL Statement ignored 

查看报错信息,还是因为wjq1没有dba_objects的权限,所以创建过程失败。

此时,如果在方法定义上加入authid current_user关键字,就可以将存储过程变化为调用者权限。

WJQ1@seiang11g>create or replace
procedure proc_wjq1_1 authid current_user is

  2  i number;

  3  begin

  4     select count(*) into i from dba_objects;

  5     dbms_output.put_line(to_char(i));

  6  end;

  7  /

Warning: Procedure created
with compilation errors.

WJQ1@seiang11g>

WJQ1@seiang11g>select
name,line,text from user_errors;

NAME                  LINE TEXT

--------------- ----------
--------------------------------------------------

PROC_WJQ1_1              4
PL/SQL: ORA-00942: table or view does not exist

PROC_WJQ1_1              4 PL/SQL: SQL Statement ignored 

显然,还在因为wqj1用户没有权限访问dba_objects而报错,毕竟不管是什么体系,wjq1目前是没有对象权限的创建过程是不会成功的。不过,为了实验成功,还是要让wjq1能顺利创建proc_wjq1_1过程。

SYS@seiang11g>grant select any
dictionary to wjq1;

Grant succeeded.

WJQ1@seiang11g>create or replace
procedure proc_wjq1_1 authid
current_user is

  2  i number;

  3  begin

  4     select count(*) into i from dba_objects;

  5     dbms_output.put_line(to_char(i));

  6  end;

  7  /

Procedure created. 

WJQ1@seiang11g>

WJQ1@seiang11g>grant execute on
proc_wjq1_1 to wjq2;

Grant succeeded.

切换到wjq2用户,注意此时它是拥有select
any dictionary权限的。

WJQ2@seiang11g>select count(*)
from dba_objects;

 
COUNT(*)

----------

    
86995

WJQ2@seiang11g>exec
wjq1.proc_wjq1_1;

86995

PL/SQL procedure successfully
completed. 

此时,wjq2执行过程成功。因为此时wjq1和wjq2都拥有select
any dictionary权限,所以即使在调用者权限下,也是会成功的。此时,如果收回wjq2上的权限,结果会如何呢?

SYS@seiang11g>revoke select any
dictionary from wjq2;

Revoke succeeded.

WJQ2@seiang11g>select count(*)
from dba_objects;

select count(*) from dba_objects

                     *

ERROR at line 1:

ORA-00942: table or view does not exist

WJQ2@seiang11g>exec
wjq1.proc_wjq1;

BEGIN wjq1.proc_wjq1; END;

           *

ERROR at line 1:

ORA-06550: line 1, column 12:

PLS-00905: object WJQ1.PROC_WJQ1 is invalid

ORA-06550: line 1, column 7:

PL/SQL: Statement ignored

此时,就看出调用者权限的差异了。wjq1始终有dba_objects的权限,而wjq2在之后被回收了select any dictionary的权限。如果是定义者权限,wjq2调用proc_wjq1_1是没有问题的。但是此时报错,说明此处使用的是wjq2的调用者权限。

       通过上述两个案例,分别通过实验对定义者权限和使用者权限进行了分析,想必大家已经有了比较深刻的认识和理解了,但是很多时候,我们都会使用存储过程Procedure来实现一些脚本功能。通过Procedure来实现一些数据库相关的维护、开发工作,可以大大提高我们日常工作效率。下面数据库运维过程中有这样一种情况需要我们DBA去处理,实际的问题这样的:

      同一个数据库中有多个Schema的内容相同,用于不同的测试目的。一些开发同步任务促使编写一个程序来实现Schema内部或者之间对象操作。从软件版本角度看,维护一份工具脚本是最好的方法,可以避免由于修改造成的版本错乱现象。如何通过一个存储过程脚本,在不同Schema下执行效果不同就成了我们需要考虑的问题?


       将上述问题简化如下:在
Schema A里面包括一个存储过程ProcA中还有一张数据表T1。在Proc代码中,包括了对表T1的操作内容。而Schema B中也存在一个数据表T1,并且B拥有一个名为Proc的私有同义词synonym指向A.Proc。问题是如何让Proc根据执行的Schema的不同,访问不同Schema中数据表?换句话说,就是如果是Schema A调用Proc程序包,操作的就是Schema A里面的数据表T1。如果B调用Proc程序包,就操作Schema B里面的数据表T1

为了对上述问题有一个明确的处理方法,下面通过以下示例进行模拟实验:

SYS@seiang11g>select * from
v$version;

BANNER

--------------------------------------------------------------------------------

Oracle
Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

PL/SQL Release 11.2.0.4.0 -
Production

CORE    11.2.0.4.0      Production

TNS for Linux: Version 11.2.0.4.0 -
Production

NLSRTL Version 11.2.0.4.0 -
Production

SYS@seiang11g>create user wjq1
identified by wjq1 default tablespace seiang;

User created.

SYS@seiang11g>create user wjq2
identified by wjq2 default tablespace seiang;

User created.

SYS@seiang11g>grant
connect,resource,create procedure,create synonym to wjq1,wjq2;

Grant succeeded.

SYS@seiang11g>select * from
dba_sys_privs where grantee in ('WJQ1','WJQ2');

GRANTEE                        PRIVILEGE                                ADM

------------------------------
---------------------------------------- ---

WJQ1                           CREATE SYNONYM                           NO

WJQ2                           UNLIMITED
TABLESPACE                     NO

WJQ2                           CREATE SYNONYM                           NO

WJQ1                           UNLIMITED
TABLESPACE                     NO

WJQ2                           CREATE
PROCEDURE                         NO

WJQ1                           CREATE PROCEDURE                         NO

6 rows selected. 

在Schema
wjq1下面创建数据表和相应的存储过程。

 WJQ1@seiang11g>create table
tab_wjq(name varchar2(20));

Table created.

WJQ1@seiang11g>create or replace
procedure proc_wjq1(v_name varchar2) is

  2  begin

  3     insert into tab_wjq values(v_name);

  4     commit;

  5  end proc_wjq1;

  6  /

Procedure created.

Schema wjq1进行执行存储过程

WJQ1@seiang11g>exec
proc_wjq1('wjq');

PL/SQL procedure successfully
completed.

WJQ1@seiang11g>select * from
tab_wjq;

NAME

--------------------

wjq 

将过程proc_wjq1的权限赋予Schema
wjq2

 WJQ1@seiang11g>grant execute on
proc_wjq1 to wjq2;

Grant succeeded. 

另外创建Schema
wjq2数据表对象,并且包括同义词对象。

 WJQ2@seiang11g>create table
tab_wjq(name varchar2(20));

Table created.

WJQ2@seiang11g>create synonym proc_wjq1
for wjq1.proc_wjq1;

Synonym created.

WJQ2@seiang11g>select * from
user_synonyms;

SYNONYM_NAME    TABLE_OWNER     TABLE_NAME           DB_LINK

--------------- ---------------
-------------------- ------------------------------

PROC_WJQ1       WJQ1            PROC_WJQ1 

进行默认情况测试,在Schema
wjq2中调用存储过程proc_wjq1,查看操作的是哪一个Schema下的数据表

WJQ2@seiang11g>exec
proc_wjq1('seiang');

PL/SQL procedure successfully
completed.

WJQ2@seiang11g>select * from
tab_wjq;

no rows selected

Schema wjq2中数据表tab_wjq没有数据,查看Schema
wjq1中数据表情况:

WJQ1@seiang11g>select * from
tab_wjq;

NAME

--------------------

wjq

seiang 

上述实验说明:在默认情况下,不同Schema对象调用相同存储过程,其中涉及到的对象都是相同的。也就是Oracle存储过程中的“定义者权限”。一旦用户拥有执行存储过程的权限,就意味着在执行体中,使用的是定义者的权限体系。

       那么这个问题似乎是没有办法。执行体指向的是Schema
wjq1的数据表tab_wjq。

与定义者权限对应的就是“调用者权限”。也就说,对用户是否可以执行该程序体中的对象,完全取决于执行调用用户系统权限和对象权限(注意:非角色权限)。大胆的猜想,如果使用调用者权限,从执行用户权限角度看,是不是可以直接访问自己Schema中的对象了?下面通过实验进行验证:

 WJQ1@seiang11g>create or replace
procedure proc_wjq1(v_name varchar2) authid current_user is

  2  begin

  3     insert into tab_wjq values(v_name);

  4     commit;

  5  end proc_wjq1;

  6  /

Procedure created.

在用户wjq1中进行实验,结果:

WJQ1@seiang11g>exec
proc_wjq1('wjqbest');

PL/SQL procedure successfully
completed.

WJQ1@seiang11g>select * from tab_wjq;

NAME

--------------------

wjq

seiang

wjqbest

转换到用户wjq2中,进行实验:

 WJQ2@seiang11g>exec
proc_wjq1('seiangbest');

PL/SQL procedure successfully
completed.

WJQ2@seiang11g>select * from
tab_wjq;

NAME

--------------------

seiangbest 

从上面的实验结果可以发现:在调用者权限模式下,可以实现调用Schema下数据表优先的效果。如果此时Schema
wjq2中没有数据表tab_wjq,结果又会如何呢?

 WJQ2@seiang11g>drop table tab_wjq;

Table dropped.

WJQ2@seiang11g>exec
proc_wjq1('hahaha');

BEGIN proc_wjq1('hahaha'); END;

*

ERROR at line 1:

ORA-00942: table or view does not exist

ORA-06512: at "WJQ1.PROC_WJQ1", line 3

ORA-06512: at line 1

如果wjq2用户拥有wjq1用户下的数据表tab_wjq的权限,结果又会如何呢?

 WJQ1@seiang11g>grant all on
tab_wjq to wjq2;

Grant succeeded.

WJQ2@seiang11g>select * from
wjq1.tab_wjq;

NAME

--------------------

wjq

seiang

wjqbest

WJQ2@seiang11g>exec
proc_wjq1('hahaha');

BEGIN proc_wjq1('hahaha'); END;

*

ERROR at line 1:

ORA-00942: table or view does not exist

ORA-06512: at "WJQ1.PROC_WJQ1", line 3

ORA-06512: at line 1

从上面的结果发现,即使wjq2拥有wjq1下数据表tab_wjq的权限,在使用调用者权限时,也是只能操作自己Schema下的对象。所以定义者权限和调用者权限,是Oracle存储过程中两个重要的概念对象,一些麻烦场景下应用往往有不错的效果。

感谢各位的阅读!关于“Oracle中定义者权限和调用者权限的示例分析”这篇文章就分享到这里了,希望

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/144265.html

(0)

相关推荐

  • MySQL数据库升级的坑有哪些

    技术MySQL数据库升级的坑有哪些这篇文章主要介绍“MySQL数据库升级的坑有哪些”,在日常操作中,相信很多人在MySQL数据库升级的坑有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”

    攻略 2021年10月28日
  • 简单说下 systemui

    技术简单说下 systemui 简单说下 systemui简单说下 systemui
    因为最近在进行一些 systemui 的开发,所以想简单地介绍一下笔者现在所认知的 systemui(目前的了解还是

    礼包 2021年12月2日
  • 文件夹选项怎么打开,怎么把文件夹选项找回来呀。。

    技术文件夹选项怎么打开,怎么把文件夹选项找回来呀。。让“文件夹选项”显示的方法有两个文件夹选项怎么打开。 方法一:组策略 点击“开始→运行”,在运行对话框中输入“gpedit.msc”命令,点击“确定”按钮后,弹出“组策

    生活 2021年10月28日
  • 怎么发短信,在网络上手机短信怎么发求答案

    技术怎么发短信,在网络上手机短信怎么发求答案新浪UC每天免费发十五条怎么发短信,如果超过这个数一条一角钱,不过得先用手机绑定,15条之内不花钱,还有一个是网易泡泡,这个软件和上面的UC一样也是通过时间来换取东西,UC换的

    生活 2021年10月26日
  • 关系型数据库的设计规则有哪些

    技术关系型数据库的设计规则有哪些本篇内容介绍了“关系型数据库的设计规则有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成

    攻略 2021年12月11日
  • Python异常处理的关键词与结构有哪些

    技术Python异常处理的关键词与结构有哪些这篇文章主要介绍“Python异常处理的关键词与结构有哪些”,在日常操作中,相信很多人在Python异常处理的关键词与结构有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好

    攻略 2021年11月20日