Oracle允許使用幾個PL/SQL API(UTL_TCP, UTL_SMTP, UTL_MAIL, UTL_HTTP和 UTL_INADDR)訪問外部網絡服務,這些API都使用TCP協議,在上一個數據庫版本中(10g)是通過一個基於用戶是否被授予執行某個包的許可的on/off開關來實現的,Oracle 11g引入了細粒度訪問網絡服務,通過在XML DB 數據庫中使用訪問控制列表(ACL)來實現。
在從10g升級到11g時,訪問外部網絡服務時可能會產生一些混亂,在那種情況下,你需要實現合理的訪問控制列表。
1、細粒度訪問網絡服務的使用不能作爲忽略基本的安全評估的藉口,如收回與網絡服務有關程序包的不必要的權限。
2、通過限制對特定端口的訪問控制你的服務是可用的,如果你僅僅需要訪問http 80端口,指定這個端口比在服務器上開放所有端口的訪問要好得多。
3、授權時使用通配符比不使用通配符安全性更差,也更危險。
4、你必須保護你的訪問控制列表,如果有人能夠修改它們,因爲保護機制問題它們變得毫無用處,阻止直接訪問存儲在XML DB 數據庫中的訪問控制列表,確保用戶不能訪問管理API。
創建訪問控制列表
BEGIN
DBMS_NETWORK_ACL_ADMIN.create_acl (
acl => 'aaa.xml', --這個xml文件名字是隨便取的,不可以出現同名
description => 'A test of the ACL functionality', --訪問控制列表的描述信息
principal => 'TEST1', --表示賦予權限給哪個用戶
is_grant => TRUE, --true表示授予權限 false表示取消權限
privilege => 'connect',
start_date => SYSTIMESTAMP, --默認值是NULL,當指定了一個值後,訪問控制列表只有在指定的日期到達時或到達後才被激活
end_date => NULL); --訪問控制列表結束日期(可選的)
COMMIT;
END;
使用ADD_PRIVILEGE存儲過程將其他的用戶或角色添加到訪問控制列表中,它的參數與CREATE_ACL存儲過程的參數類似,省略了DESCRIPTION參數,同時增加了POSITION參數,它用於設置優先順序。
BEGIN
DBMS_NETWORK_ACL_ADMIN.add_privilege (
acl => 'aaa.xml',
principal => 'TEST2',
is_grant => FALSE,
privilege => 'connect',
position => NULL,
start_date => NULL,
end_date => NULL);
COMMIT;
END;
每個委託人在訪問控制列表中都被作爲一個獨立的訪問控制單元(ACE)進行定義,當定義了多條原則時,他們按照從上到下的順序被評估,直到最後一條定義 權限的原則,這就意味着一個拒絕訪問某個資源的角色可以被授予一個用戶,但是如果這個用戶又作爲一個委託人定義在文件中時,這個定義將覆蓋角色的定義,使用POSITION參數保證權限是按順序進行評估的。
使用DELETE_PRIVILEGE存儲過程移除權限,如果IS_GRANT或PRIVILEGE參數的值是NULL,將移除所有授予的權限。
BEGIN
DBMS_NETWORK_ACL_ADMIN.delete_privilege (
acl => 'aaa.xml',
principal => 'TEST2',
is_grant => FALSE,
privilege => 'connect');
COMMIT;
END;
使用DROP_ACL刪除訪問控制列表(刪除這個列表,那列表賦予權限的那些用戶自然也被取消相應的權限了)
BEGIN
DBMS_NETWORK_ACL_ADMIN.drop_acl (
acl => 'aaa.xml');
COMMIT;
END;
使用ASSIGN_ACL存儲過程給網絡分配訪問控制列表
BEGIN
DBMS_NETWORK_ACL_ADMIN.assign_acl (
acl => ‘aaa.xml',
host => '192.168.10.4', --主機名,域名,ip地址或分配的子網,主機名大小寫敏感,ip地址和域名允許使用通配符
lower_port => 80, --默認值是NULL,爲connect權限指定低端口範圍
upper_port => NULL); --默認值是NULL,如果指定了lower_port,同時upper_port的值爲 NULL,它就認爲upper_port等同於lower_port
END;
UNASSIGN_ACL存儲過程允許你手動刪除訪問控制列表,它使用的參數與ASSIGN_ACL存儲過程相同,使用NULL參數作爲通配符。
BEGIN
DBMS_NETWORK_ACL_ADMIN.unassign_acl (
acl => 'aaa.xml',
host => '192.168.10.4',
lower_port => 80,
upper_port => NULL);
COMMIT;
END;
DBA_NETWORK_ACLS視圖顯示關於網絡和訪問控制列表分配的信息。
DBA_NETWORK_ACL_PRIVILEGES視圖顯示關於與訪問控制列表聯合的權限信息。
USER_NETWORK_ACL_PRIVILEGES視圖顯示當前用戶網絡訪問控制列表設置。
權限檢查
除了訪問控制列表視圖外,還可以使用DBMS_NETWORK_ACL_ADMIN包中的CHECK_PRIVILEGE和CHECK_PRIVILEGE_ACLID函數來檢查權限。
SELECT DECODE(DBMS_NETWORK_ACL_ADMIN.check_privilege('aaa.xml', 'TEST1', 'connect'),1, 'GRANTED', 0, 'DENIED', NULL) privilege
FROM dual; --返回1表示權限被授予,0表示權限被拒絕;null表示權限沒有被授予或者拒絕
SELECT acl,
host,
DECODE(DBMS_NETWORK_ACL_ADMIN.check_privilege_aclid(aclid, 'TEST2', 'connect'),1, 'GRANTED', 0, 'DENIED', NULL) privilege
FROM dba_network_acls;
可參考官網:http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_networkacl_adm.htm