對定義者許可權和呼叫者許可權的理解

llnnmc發表於2017-09-09

對於PL/SQL儲存過程的呼叫來說,具有兩種許可權控制方式:定義者許可權和呼叫者許可權。定義者許可權表示使用者在執行PL/SQL程式碼的時候,是否有權訪問程式碼中所涉及的物件如表等,是根據建立該PL/SQL的使用者是否擁有對其訪問權來決定的,而呼叫者許可權則是根據執行該PL/SQL的使用者是否具有對其中涉及的物件的訪問權來決定是否可訪問的。預設情況下,PL/SQL儲存過程都是以定義者許可權來執行的。以下例子說明了其含義。

建立一個使用者u1,該使用者試圖去訪問hr使用者的表employees,但因為沒有許可權而失敗
conn / as sysdba
create user u1 identified by u1;
grant connect, resource to u1;
conn u1/u1
select last_name from hr.employees where employee_id=101;

ERROR at line 1:
ORA-00942: table or view does not exist

現在hr使用者建立一個儲存過程,並在其中實現對錶employees的訪問
conn hr/hr
create or replace procedure p_get_lastname1(v_employee_id in employees.employee_id%type,
                                            v_last_name   out employees.last_name%type) is
begin
    select last_name
      into v_last_name
      from employees
     where employee_id = v_employee_id;
end;
/

現在把執行該儲存過程的許可權賦給u1使用者,u1使用者便可以透過該儲存過程間接實現對錶employees的訪問
grant execute on p_get_lastname1 to u1;
conn u1/u1
var ls_lastname varchar2(50);
exec hr.p_get_lastname1(101,:ls_lastname);

PL/SQL procedure successfully completed.

print ls_lastname;

LS_LASTNAME
------------------------
Kochhar

這裡之所以能訪問就是利用了PL/SQL預設的定義者許可權機制,因為該儲存過程是由hr使用者自己定義的,hr使用者自然可以訪問自己的表。因此借用定義者許可權,u1使用者雖然本身沒有對錶employees的訪問權,但藉助儲存過程同樣實現了對該表的訪問。

再看呼叫者許可權的使用,現在建立另一個使用者u2,以u2來執行hr使用者建立的另一個儲存過程
conn / as sysdba
create user u2 identified by u2;
grant connect,resource to u2;
conn hr/hr
create or replace procedure p_get_lastname2(v_employee_id in employees.employee_id%type,
                                            v_last_name   out employees.last_name%type)
    authid current_user is
begin
    select last_name
      into v_last_name
      from employees
     where employee_id = v_employee_id;
end;
/
grant execute on p_get_lastname2 to u2;
conn u2/u2
var ls_lastname varchar2(50);
exec hr.p_get_lastname2(101,:ls_lastname);

ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at "HR.P_GET_LASTNAME2", line 5
ORA-06512: at line 1

這裡之所以執行失敗是因為儲存過程在定義時被指定為呼叫者許可權(透過authid current_user指定),而呼叫者u2沒有訪問employees表的許可權,因此執行沒有成功。

對於定義者許可權的PL/SQL程式來說,透過角色傳入的許可權是不能作用於儲存過程裡面的。以下例子說明了這點
conn / as sysdba
create user u3 identified by u3;
grant dba to u3;
conn u3/u3
create or replace procedure p_test is
begin
    dbms_utility.exec_ddl_statement('grant dba to u1');
end;
/
exec p_test;

ERROR at line 1:
ORA-01932: ADMIN option not granted for role 'DBA'
ORA-06512: at "SYS.DBMS_UTILITY", line 574
ORA-06512: at "U3.P_TEST", line 3
ORA-06512: at line 1

雖然u3使用者被授予了DBA許可權,但是預設指定的定義者許可權建立的儲存過程是不能獲得DBA這個角色所傳遞過來的許可權的,因此執行仍然沒有足夠的許可權,DBMS_UTILITY包無法訪問。此時可將該儲存過程改為呼叫者許可權,這樣u3使用者就能夠正常執行了。
create or replace procedure p_test authid current_user is
begin
    dbms_utility.exec_ddl_statement('grant dba to u1');
end;
/
exec p_test;

PL/SQL procedure successfully completed.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28974745/viewspace-2144738/,如需轉載,請註明出處,否則將追究法律責任。

相關文章