定義者權限和調用者權限的區別

正如大家所知,Oracle從8i開始引入了調用者權限體系結構,之前一直使用定義者權限體系結構。關於定義者權限與調用者權限之間的相通點或者是各自優勢本文不做探討,這裏僅描述調用者權限與定義者權限之間的差異,在我看來,主要有三個方面:

1、執行的schema不同,操作的對象也不同
在定義者(definer)權限下,執行的用戶操作的schema爲定義者,所操作的對象是定義者在編譯時指定的對象。
在調用者(invoker)權限下,執行的用戶操作的schema爲當前用戶,所操作的對象是當前模式下的對象。
例如:
[php]
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
  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>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;
Current User:   TMPA
Session User:   TMPA
Current Schema: TMPA
Tables Value:    I'm ownered by user:tmpa

PL/SQL 過程已成功完成。
[/php]
可以看到,對於owner所擁有的對象,當前用戶和session用戶都是當前執行過程的用戶;

新開一個連接,以tmpb用戶登陸再執行看看:
[php]
E:\ora10g>sqlplus tmpb/tmpb

連接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> set sqlprompt TMPB>
TMPB>create table tmptbl(str varchar2(50));

表已創建。

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

已創建 1 行。

TMPB>commit;

提交完成。

TMPB>set serveroutput on
TMPB>exec tmpa.definer_proc;
Current User:   TMPA
Session User:   TMPB
Current Schema: TMPA
Tables Value:    I'm ownered by user:tmpa

PL/SQL 過程已成功完成。

TMPB>exec tmpa.invoker_proc;
Current User:   TMPB
Session User:   TMPB
Current Schema: TMPB
Tables Value:    I'm ownered by user:tmpb

PL/SQL 過程已成功完成。
[/php]

調用非owner的過程,對於定義者權限的過程,雖然session是tmpb,但當前用戶仍然是tmpa,訪問的對象也是tmpa的表,而對於調用者權限的過程,當前session和用戶都是當前執行過程的用戶tmpb,而且訪問的對象也是當前用戶的對象。

2、執行的權限不同
在定義者(definer)權限下,當前用戶的權限爲角色無效情況下所擁有的權限。
在調用者(invoker)權限下,當前用戶的權限爲當前所擁有的權限(含角色)。
例如:
仍用前文中的用戶
[php]
TMPA>create or replace procedure createtbl_definer as
  2  begin
  3    execute immediate 'create table tmptbl2 (id number)';
  4  end;
  5  /

過程已創建。

TMPA>create or replace procedure createtbl_invoker AUTHID CURRENT_USER as
  2  begin
  3    execute immediate 'create table tmptbl2 (id number)';
  4  end;
  5  /

過程已創建。
--
[/php]

首先執行定義者權限過程:
[php]
TMPA>exec createtbl_definer;
BEGIN createtbl_definer; END;

*
第 1 行出現錯誤:
ORA-01031: 權限不足
ORA-06512: 在 "TMPA.CREATETBL_DEFINER", line 3
ORA-06512: 在 line 1
--
[/php]
由於角色無效,相當於當前用戶沒有了建表權限,因此創建失敗,這也正是爲什麼過程中執行DDL語句需要顯示授權的原因。

[php]
TMPA>exec createtbl_invoker;

PL/SQL 過程已成功完成。

TMPA>desc tmptbl2
名稱                                      是否爲空? 類型
----------------------------------------- -------- ----------------------------
ID                                                 NUMBER
--
[/php]
執行調用者權限過程,能夠成功創建!


3、執行的效率不同
在定義者(definer)權限下,過程被靜態編譯靜態執行(相對而言),所執行sql語句在共享區池中是可被共享使用的
在調用者(invoker)權限下,過程靜態編譯,但動態執行,雖然執行的語句相同,但不同用戶執行,其sql語句在共享池中並不能共享。

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

發佈了1 篇原創文章 · 獲贊 3 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章