天天看點

關于視圖和存儲過程的權限問題探究

今天在處理一個工單的時候發現了一個奇怪的現象,開發同學需要建立一個存儲過程,目前的架構類似這樣的形式

關于視圖和存儲過程的權限問題探究

資料庫中存在一個屬主使用者,表,存儲過程等對象都建立在這個使用者上,而另外有一些連接配接使用者,根據業務和功能可能通路的對象權限也有所不同。是以就會出現一個owner,多個connect user的情況。這種方式可以減少很多誤操作,權限控制更為細粒度。

現在的問題是在owner使用者上建立存儲過程,存儲過程會引用若幹張表,都在owner使用者下,而connect user下則沒有這些表相關的任何同義詞。看起來好像是不大合理啊,至少感覺資訊不夠完整,于是和開發的同學進行了确認,他們回報這個存儲過程一直是connect user執行,沒有任何問題,當然在處理完之後,我還是帶着疑惑測試了一遍,發現果真如此,開始讓我有一種毀三觀的感覺。

我們來測試一下,步驟很明确,先來初始化資料,建立兩個使用者,一個owner,一個connect user,然後建立一個存儲過程,模拟當時的問題。

create user testo identified by oracle;

create user testc identified by oracle;

grant connect to testc;

grant connect,resource to testo;

alter session set current_schema=testo;

建立表test_bind,需要在後面的存儲過程中引用,保證表中有存儲過程調用合适的資料。

create table test_bind as select object_id cn,object_id cid from all_objects;

update test_bind set cn=100 where rownum<2;

update testo.test_bind set cn=101 where cn=100 and rownum<2   ;

SQL> select count(*) from testo.test_bind where cn=100;

  COUNT(*)

----------

         1

建立存儲過程

create or replace procedure test_proc

AS

tmp_cid test_BIND.CID%TYPE;

BEGIN

        SELECT CID INTO tmp_cid

        FROM test_BIND WHERE CN = 100;

dbms_output.put_line(tmp_cid);

END;

/

賦予權限,建立存儲過程的同義詞,注意此處是沒有建立表的同義詞

grant execute on testo.test_proc to testc;

create synonym testc.test_proc for testo.test_proc;

開始複現問題:

alter session set current_schema=testc;

set serveroutput on

存儲過程調用沒有問題

SQL> exec test_proc;

100

PL/SQL procedure successfully completed.

檢視test_bind這個表是否可通路

SQL> desc testc.test_BIND

ERROR:

ORA-04043: object testc.test_BIND does not exist

小結 由此可以看出,owner使用者上的存儲過程,裡面涉及的表在connect 使用者上沒有對應的同義詞時,存儲過程調用沒有問題。可見存儲過程的執行是完全基于owner使用者的。

當然存儲過程的權限問題了解了,我的印象中視圖似乎也有點矯情,有時候權限的要求比較高。在此一并矯正一下錯誤的觀點。

我們建立一個新的connect使用者testc2,然後測試視圖的情況。

如果我們在owner使用者上建立視圖,測試一下是否權限也會有類似的問題。

create user testc2 identified by oracle;

grant connect to testc2;

建立角色testo_role,所有的權限都通過testo_role來控制

create role testo_role;

建立視圖

create view view_test_bind as select *from test_bind;

給角色testo_role賦予權限

grant select on view_test_bind to testo_role;

角色賦予connect使用者testc2

grant testo_role to testc2;

alter session set current_schema=testc2;

建立同義詞

create synonym testc2.view_test_bind for testo.view_test_bind;

檢視視圖的結構

desc testc2.view_test_bind

 Name                                      Null?    Type

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

 CN                                        NOT NULL NUMBER

 CID                                       NOT NULL NUMBER

檢視owner下的表test_bind是否可以在testc2下通路

SQL> desc testc2.test_bind

ORA-04043: object testc2.test_bind does not exist

小結

由此可以看出情況和存儲過程是類似的

那麼關于視圖還有什麼矯情的問題呢。印象中是有的。

我們在connect使用者上建立視圖

先把通路testo.test_bind的權限給角色testo_role

grant select on testo.test_bind to testo_role;

然後建立同義詞

create synonym testc2.test_bind for testo.test_bind;

在connect使用者下建立視圖

SQL> create view view_test_bind as select *from testc2.test_bind;

create view view_test_bind as select *from testc2.test_bind

                                                  *

ERROR at line 1:

ORA-01031: insufficient privileges

而賦予了對象權限之後,視圖的建立就引刃而解了。

是以對于視圖而言,在連接配接使用者上建立視圖需要對象權限而角色權限會有限制。

是以推薦的架構方式為:

關于視圖和存儲過程的權限問題探究

下面是我的公衆号二維碼,歡迎掃描關注。

關于視圖和存儲過程的權限問題探究