使用 Authid Current_User 為呼叫者授權

531968912發表於2016-08-03
Authid Current_User 是呼叫者許可權。
oracle DB下面有2種執行的許可權:定義者許可權和呼叫者許可權。
預設都是定義者許可權。宣告Authid Current_User後就是呼叫者許可權。

定義者許可權的現象是,如果在APPS下建立的procedure,那其他user,只要能執行procedure,都是以apps的名義來執行的。因為APPS是procedure的定義者。
APPS能做什麼,那這個procedure就能做什麼。

呼叫者許可權的現象是,如果在APPS下建立的procedure,如果其他user有許可權執行這個procedure,這個procedure所做的內容都是以當前user的名義來做的。如果某個table,只有APPS才有許可權修改,那這個procedure在apps下面才執行成功。其他user下是不成功的。
我在一些技術論壇裡面,常常看到有朋友問這種問題: 為什麼我的使用者具有DBA許可權,卻無法在儲存過程裡面建立一張普通表呢?
 
下面就結合具體案例來談談這個問題:
 
SQL> conn eric/eric; Connected.
SQL> select * from dba_role_privs where grantee='ERIC';   GRANTEE                        GRANTED_ROLE                   ADM DEF ------------------------------ ------------------------------ --- --- ERIC                           DBA                            NO  YES ERIC                           CONNECT                        NO  YES ERIC                           RESOURCE                       NO  YES ERIC                           RECOVERY_CATALOG_OWNER         NO  YES
可以看到,使用者eric擁有 DBA 許可權!
 
 
用此使用者建立一個儲存過程:
create or replace procedure p_CreateTable  as begin  execute immediate 'create table test_tb(id number)'; end p_CreateTable; /
Procedure created.
執行時會發現,系統提示許可權不足(insufficient privileges)!
SQL> exec p_CreateTable; BEGIN p_CreateTable; END;   * ERROR at line 1: ORA-01031: insufficient privileges ORA-06512: at "ERIC.P_CREATETABLE", line 3 ORA-06512: at line 1  
由上可以看到,即使擁有DBA role,也不能建立表。
即 role在儲存過程中不可見!
查閱資料發現:
Oracle8i以前的版本,所有已編譯儲存物件,包括packages, procedures, functions, triggers, views等,只能以定義者(Definer)身份解析執行;
而Oracle8i及其後的新版本,Oracle引入呼叫者(invoker)許可權,使得物件可以以呼叫者身份和許可權執行。
遇到這種情況,通常解決方法是進行顯式的系統許可權: grant create table to eric;
但是,此方法太笨,因為有可能執行一個儲存過程,需要很多不同許可權(oracle對許可權劃分粒度越來越細)。
 
最好的方法是,利用 oracle 提供的方法,在建立儲存過程時,加入 Authid Current_User 條件進行許可權分配。
 
create or replace procedure p_CreateTable Authid Current_User  as  begin  execute immediate 'create table test_tb(id number)'; end p_CreateTable; /
Procedure created.  
SQL> exec p_CreateTable;   PL/SQL procedure successfully completed.
SQL> desc test_tb  Name                                      Null?    Type  ----------------------------------------- -------- ----------------------------  ID                                                 NUMBER
 成功啦!!!
 
由此可以引申出一個問題:
 
如果使用者B要執行A使用者的某儲存過程,傳統的解決方案是:
 
A使用者將此儲存過程的執行許可權賦予B使用者: grant execute on p_test to B;
 
在B使用者下建立一個同義詞: create synonym p_test for a.p_test;
 
然後B使用者就可以直接執行p_test了.
但是,如果使用 Authid Current_User 選項,在建立時給呼叫者授權,就簡單多了!

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

相關文章