天天看點

Oracle 定義者權限與調用者權限(AUTHID CURRENT_USER)

oracle定義者權限與調用者權限(authid current_user)

參考:

http://blog.itpub.net/7607759/viewspace-166557/

http://blog.itpub.net/7607759/viewspace-166558

http://blog.163.com/l_yongfei/blog/static/265673042009420103210297/

正如大家所知,oracle從8i開始引入了調用者權限體系結構,之前一直使用定義者權限體系結構。

一、簡單介紹一下二者的使用方法

oracle建立存儲過程時,若不指定authid參數,則調用權限驗證預設是definer,也就是存儲過程執行時,以這個存儲過程的建立者的身份來驗 證存取權限;可以在建立存儲過程時指定authid為current_user,進而在執行存儲過程時根據目前調用存儲過程的使用者權限來驗證。

舉個例子說明:

比如有兩個使用者test和user1,test使用者下有個表user1table,使用者user1隻有這個表的select權限。test建立了一個存儲 過程testproc,使用預設的authid調用方式,存儲過程内容為“insert into user1table ....”,然後使用grant execute on testproc to user1将執行權限賦予user1,那麼user1就可以調用這個存儲過程向user1table添加資料。注意:此時user1并沒有對表 user1table的insert權限,但由于testproc執行的時候,是根據test使用者的權限來驗證的,是以insert語句不會出現權限不足 的提示。

假如建立testproc是添加了authid current_user,則當user1調用test.testproc存儲過程時,就會報兩個錯誤:一是user1table未定義,二是對 user1table沒有insert權限。對于第一個問題,原因是user1table僅在test使用者模式下,user1使用者不能直接引用,可以在定 義testproc時使用test.user1table方式;對于第二個問題,由于user1沒有對user1table的insert權限,是以無法 執行這個存儲過程,除非給user1使用者增加user1table表的insert權限。

二、定義者權限與調用者權限之間差異

關于定義者權限與調用者權限之間的相通點或者是各自優勢本文不做探讨,這裡僅描述調用者權限與定義者權限之間的差異,在我看來,主要有三個方面:

1、執行的schema不同,操作的對象也不同

l 在定義者(definer)權限下,執行的使用者操作的schema為定義者,所操作的對象是定義者在編譯時指定的對象。

l 在調用者(invoker)權限下,執行的使用者操作的schema為目前使用者,所操作的對象是目前模式下的對象。

例如:

e:\ora10g>sqlplus "/ as sysdba"

連接配接到:

oracle database 10g enterprise edition release 10.2.0.3.0 - production

with the partitioning, olap and data mining options

sql>create user tmpa identified by tmpa;

使用者已建立。

sql>grant connect,resource to tmpa;

授權成功。

sql>create user tmpb identified by tmpb;

sql>grant connect,resource to tmpb;

sql>conn tmpa/tmpa

已連接配接。

sql>set sqlprompt tmpa>

tmpa>create table tmptbl(str varchar2(50));

表已建立。

tmpa>insert into tmptbl values ('i''m ownered by user:tmpa');

已建立 1 行。

tmpa>commit;

送出完成。

tmpa>create or replace procedure definer_proc as

  2  begin

  3    for x in (select sys_context('userenv', 'current_user') current_user,

  4                     sys_context('userenv', 'session_user') session_user,

  5                     sys_context('userenv', 'current_schema') current_schema,

  6                     str

  7                from tmptbl) loop

  8      dbms_output.put_line('current user:   ' || x.current_user);

  9      dbms_output.put_line('session user:   ' || x.session_user);

 10      dbms_output.put_line('current schema: ' || x.current_schema);

 11      dbms_output.put_line('tables value:    ' || x.str);

 12    end loop;

 13  end;

 14  /

過程已建立。

tmpa>create or replace procedure invoker_proc authid current_user as

tmpa>set serveroutput on

tmpa>grant execute on definer_proc to tmpb;

tmpa>grant execute on invoker_proc to tmpb;

tmpa>exec definer_proc;

current user:   tmpa

session user:   tmpa

current schema: tmpa

tables value:    i'm ownered by user:tmpa

pl/sql 過程已成功完成。

tmpa>exec invoker_proc;

可以看到,對于owner所擁有的對象,目前使用者和session使用者都是目前執行過程的使用者;

新開一個連接配接,以tmpb使用者登陸再執行看看:

e:\ora10g>sqlplus tmpb/tmpb

sql> set sqlprompt tmpb>

tmpb>create table tmptbl(str varchar2(50));

tmpb>insert into tmptbl values ('i''m ownered by user:tmpb');

tmpb>commit;

tmpb>set serveroutput on

tmpb>exec tmpa.definer_proc;

session user:   tmpb

tmpb>exec tmpa.invoker_proc;

current user:   tmpb

current schema: tmpb

tables value:    i'm ownered by user:tmpb

調用非owner的過程,對于定義者權限的過程,雖然session是tmpb,但目前使用者仍然是tmpa,通路的對象也是tmpa的表,而對于調用者權限的過程,目前session和使用者都是目前執行過程的使用者tmpb,而且通路的對象也是目前使用者的對象。

2、執行的權限不同

l 在定義者(definer)權限下,目前使用者的權限為角色無效情況下所擁有的權限。

l 在調用者(invoker)權限下,目前使用者的權限為目前所擁有的權限(含角色)。

仍用前文中的使用者

tmpa>create or replace procedure createtbl_definer as

  3    execute immediate 'create table tmptbl2 (id number)';

  4  end;

  5  /

tmpa>create or replace procedure createtbl_invoker authid current_user as

首先執行定義者權限過程:

tmpa>exec createtbl_definer;

begin createtbl_definer; end;

*

第 1 行出現錯誤:

ora-01031: 權限不足

ora-06512: 在 "tmpa.createtbl_definer", line 3

ora-06512: 在 line 1

由于角色無效,相當于目前使用者沒有了建表權限,是以建立失敗,這也正是為什麼過程中執行ddl語句需要顯示授權的原因。

tmpa>exec createtbl_invoker;

tmpa>desc tmptbl2

 名稱                                      是否為空? 類型

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

 id                                                 number

執行調用者權限過程,能夠成功建立!

3、執行的效率不同

l 在定義者(definer)權限下,過程被靜态編譯靜态執行(相對而言),所執行sql語句在共享區池中是可被共享使用的

l 在調用者(invoker)權限下,過程靜态編譯,但動态執行,雖然執行的語句相同,但不同使用者執行,其sql語句在共享池中并不能共享。

歸根結底,正如tom所說,調用者權限體系結構的确擁有非常強大的功能,但隻有當你使用得當時才能感受到其優勢。