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