Oracle允许使用几个PL/SQL API(UTL_TCP, UTL_SMTP, UTL_MAIL, UTL_HTTP和 UTL_INADDR)访问外部网络服务,这些API都使用TCP协议,在上一个数据库版本中(10g)是通过一个基于用户是否被授予执行某个包的许可的 on/off开关来实现的,Oracle 11g引入了细粒度访问网络服务,

  通过在XML DB 数据库中使用访问控制列表(ACL)来实现,允许控制哪个用户能够访问哪个网络资源,而不关心包的授权。

   使用FTP或WebDav可以直接在XML DB 数据库中创建、修改和删除访问控制列表,Oracle提供了DBMS_NETWORK_ACL_ADMIN和 DBMS_NETWORK_ACL_UTILITY程序包允许从PL/SQL管理访问控制列表,这些API就是本文的主角。

  创建一个访问控制列表(ACL)

  访问控制列表是使用DBMS_NETWORK_ACL_ADMIN程序包来操作的,CREATE_ACL存储过程使用下面的参数来创建一个新的访问控制列表:

   ? acl - 访问控制列表XML文件的名字,产生在XML DB 数据库中的/sys/acls目录下? description - 访问控制列表的描述信息? principal - 第一个被授予或拒绝的用户账号,大小写敏感? is_grant - TRUE意味着授予了权限,FALSE意味着权限被拒绝? privilege - 给UTL_TCP, UTL_SMTP, UTL_MAIL和UTL_HTTP授予connect权限,给UTL_INADDR名称/ip解析授予resolve权限,大小写敏感? start_date - 默认值是NULL,当指定了一个值后,访问控制列表只有在指定的日期到达时或到达后才被激活? en_date - 访问控制列表结束日期(可选的)

  下面的代码创建了两个测试用户充当委托人,然后又创建了一个新的访问控制列表。

  CONN sys/password@db11g AS SYSDBA

  CREATE USER test1 IDENTIFIED BY test1;

  GRANT CONNECT TO test1;

  CREATE USER test2 IDENTIFIED BY test2;

  GRANT CONNECT TO test2;

  BEGIN

  DBMS_NETWORK_ACL_ADMIN.create_acl (

  acl => 'test_acl_file.xml',

  description => 'A test of the ACL functionality',

  principal => 'TEST1',

  is_grant => TRUE,

  privilege => 'connect',

  start_date => SYSTIMESTAMP,

  end_date => NULL);

  COMMIT;

  END;

  /

  一旦创建完毕,访问控制列表就能够在http://host:port/sys/acls目录下看到。

  使用ADD_PRIVILEGE存储过程将其他的用户或角色添加到访问控制列表中,它的参数与CREATE_ACL存储过程的参数类似,省略了DESCRIPTION参数,同时增加了POSITION参数,它用于设置优先顺序。

  BEGIN

  DBMS_NETWORK_ACL_ADMIN.add_privilege (

  acl => 'test_acl_file.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 => 'test_acl_file.xml',

  principal => 'TEST2',

  is_grant => FALSE,

  privilege => 'connect');

  COMMIT;

  END;

  /

  使用DROP_ACL删除访问控制列表

  BEGIN

  DBMS_NETWORK_ACL_ADMIN.drop_acl (

  acl => 'test_acl_file.xml');

  COMMIT;

  END;

  / 转贴 给网络分配一个访问控制列表

  使用ASSIGN_ACL存储过程给网络分配访问控制列表,它有下面一些参数:

   ? acl - 访问控制列表XML文件的名字? host - 主机名,域名,ip地址或分配的子网,主机名大小写敏感,ip地址和域名允许使用通配符? lower_port - 默认值是NULL,为connect权限指定低端口范围? upper_port - 默认值是NULL,如果指定了lower_port,同时upper_port的值为 NULL,它就认为upper_port等同于lower_port

  下面的代码展示了前面创建的访问控制列表被分配一个特定的ip地址和一个子网。

  BEGIN

  DBMS_NETWORK_ACL_ADMIN.assign_acl (

  acl => 'test_acl_file.xml',

  host => '192.168.2.3',

  lower_port => 80,

  upper_port => NULL);

  DBMS_NETWORK_ACL_ADMIN.assign_acl (

  acl => 'test_acl_file.xml',

  host => '10.1.10.*',

  lower_port => NULL,

  upper_port => NULL);

  COMMIT;

  END;

  /

   只有一个访问控制列表可以分配给一个特殊的主机+端口范围的组合,给主机+端口范围分配一个新的访问控制列表将导致前面分配的访问控制列表被删除,在你 开始一个新的分配操作时要特别留意前一个访问控制列表关闭的端口现在又被你打开了,因此分配给192.168.2.3:80的访问控制列表的优先级比分配 给192.168.2.*的访问控制列表要高。

  UNASSIGN_ACL存储过程允许你手动删除访问控制列表,它使用的参数与ASSIGN_ACL存储过程相同,使用NULL参数作为通配符。

  BEGIN

  DBMS_NETWORK_ACL_ADMIN.unassign_acl (

  acl => 'test_acl_file.xml',

  host => '192.168.2.3',

  lower_port => 80,

  upper_port => NULL);

  COMMIT;

  END;

  /

  访问控制列表视图

  DBA_NETWORK_ACLS, DBA_NETWORK_ACL_PRIVILEGES和USER_NETWORK_ACL_PRIVILEGES视图显示当前的访问控制列表设置,下面预期的输出认为没有执行过delete/drop/unassign操作。

  DBA_NETWORK_ACLS视图显示关于网络和访问控制列表分配的信息。

  COLUMN host FORMAT A30

  COLUMN acl FORMAT A30

  SELECT host, lower_port, upper_port, acl

  FROM dba_network_acls;

  HOST

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

  10.1.10.*

  192.168.2.3

  LOWER_PORT UPPER_PORT ACL---------- ---------- ------------------------------ /sys/acls/test_acl_file.xml

  80 80 /sys/acls/test_acl_file.xml

  2 rows selected.

  SQL>

  DBA_NETWORK_ACL_PRIVILEGES视图显示关于与访问控制列表联合的权限信息。

  COLUMN acl FORMAT A30

  COLUMN principal FORMAT A30

  SELECT acl,

  principal,

  privilege,

  is_grant,

  TO_CHAR(start_date, 'DD-MON-YYYY') AS start_date,

  TO_CHAR(end_date, 'DD-MON-YYYY') AS end_date

  FROM dba_network_acl_privileges;

  ACL PRINCIPAL

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

  /sys/acls/test_acl_file.xml TEST1

  /sys/acls/test_acl_file.xml TEST2

  PRIVILE IS_GR START_DATE END_DATE------- ----- ----------- -----------connect true 02-APR-2008connect false2 rows selected.

  SQL>

  USER_NETWORK_ACL_PRIVILEGES视图显示当前用户网络访问控制列表设置。

  CONN test1/test1@db11g

  COLUMN host FORMAT A30

  SELECT host, lower_port, upper_port, privilege, status

  FROM user_network_acl_privileges;

  HOST LOWER_PORT UPPER_PORT PRIVILE STATUS

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

  10.1.10.* connect GRANTED

  192.168.2.3 80 80 connect GRANTED

  2 rows selected.

  SQL>

  CONN test2/test2@db11g

  COLUMN host FORMAT A30

  SELECT host, lower_port, upper_port, privilege, status

  FROM user_network_acl_privileges;

  HOST LOWER_PORT UPPER_PORT PRIVILE STATUS

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

  10.1.10.* connect DENIED

  192.168.2.3 80 80 connect DENIED

  2 rows selected.

  SQL> 转权限检查

  处理访问控制列表视图外,还可以使用DBMS_NETWORK_ACL_ADMIN包中的CHECK_PRIVILEGE和CHECK_PRIVILEGE_ACLID函数来检查权限。

  CONN sys/password@db11g AS SYSDBA

  SELECT DECODE(

  DBMS_NETWORK_ACL_ADMIN.check_privilege('test_acl_file.xml', 'TEST1', 'connect'),

  1, 'GRANTED', 0, 'DENIED', NULL) privilege

  FROM dual;

  PRIVILE

  -------

  GRANTED

  1 row selected.

  SQL>

  COLUMN acl FORMAT A30

  COLUMN host FORMAT A30

  SELECT acl,

  host,

  DECODE(

  DBMS_NETWORK_ACL_ADMIN.check_privilege_aclid(aclid, 'TEST2', 'connect'),

  1, 'GRANTED', 0, 'DENIED', NULL) privilege

  FROM dba_network_acls;

  PRIVILE

  -------

  DENIED

  1 row selected.

  SQL>

  DBMS_NETWORK_ACL_UTILITY包包括了帮助判断可能匹配的域的函数,DOMAINS表函数按顺序返回所有可能受影响的主机,域,ip地址或子网的集合。

  SELECT *

  FROM TABLE(DBMS_NETWORK_ACL_UTILITY.domains('oel5-11g.localdomain'));

  COLUMN_VALUE

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

  oel5-11g.localdomain

  *.localdomain

  *

  3 rows selected.

  SQL>

  SELECT *

  FROM TABLE(DBMS_NETWORK_ACL_UTILITY.domains('192.168.2.3'));

  COLUMN_VALUE

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

  192.168.2.3

  192.168.2.*

  192.168.*

  192.*

  *

  5 rows selected.

  SQL>

  DOMAIN_LEVEL函数返回主机,域,ip地址或子网的级数。

  SELECT DBMS_NETWORK_ACL_UTILITY.domain_level('oel5-11g.localdomain')

  FROM dual;

  DBMS_NETWORK_ACL_UTILITY.DOMAIN_LEVEL('OEL5-11G.LOCALDOMAIN')

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

  2

  1 row selected.

  SQL>

  SELECT DBMS_NETWORK_ACL_UTILITY.domain_level('192.168.2.3')

  FROM dual;

  DBMS_NETWORK_ACL_UTILITY.DOMAIN_LEVEL('192.168.2.3')

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

  4

  1 row selected.

  SQL>

  在为可能匹配的主机,域,ip地址或子网查询访问控制列表视图是这些函数可能非常有用。

  SELECT host,

  lower_port,

  upper_port,

  acl,

  DECODE(

  DBMS_NETWORK_ACL_ADMIN.check_privilege_aclid(aclid, 'TEST1', 'connect'),

  1, 'GRANTED', 0, 'DENIED', null) PRIVILEGE

  FROM dba_network_acls

  WHERE host IN (SELECT *

  FROM TABLE(DBMS_NETWORK_ACL_UTILITY.domains('10.1.10.191')))

  ORDER BY

  DBMS_NETWORK_ACL_UTILITY.domain_level(host) desc, lower_port, upper_port;

  HOST LOWER_PORT UPPER_PORT ACL PRIVILE

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

  10.1.10.* /sys/acls/test_acl_file.xml GRANTED

  1 row selected.

  SQL> 测试访问控制列表

  用户TEST1和TEST2分别拥有了允许的和拒绝的访问控制列表,这就意味着我们可以开始通过对比对访问外部网络服务时它们的响应来测试访问控制列表的功能,下面的代码授予了这两个用户都可以执行UTL_HTTP包的权限,然后尝试从每个用户访问一个web页面。

  CONN sys/password@db11g AS SYSDBA

  GRANT EXECUTE ON UTL_HTTP TO test1, test2;

  CONN test1/test1@db11g

  DECLARE

  l_url VARCHAR2(50) := 'http://192.168.2.3:80';

  l_http_request UTL_HTTP.req;

  l_http_response UTL_HTTP.resp;

  BEGIN

  -- Make a HTTP request and get the response.

  l_http_request := UTL_HTTP.begin_request(l_url);

  l_http_response := UTL_HTTP.get_response(l_http_request);

  UTL_HTTP.end_response(l_http_response);

  END;

  /

  PL/SQL procedure successfully completed.

  SQL>

  CONN test2/test2@db11g

  DECLARE

  l_url VARCHAR2(50) := 'http://192.168.2.3:80';

  l_http_request UTL_HTTP.req;

  l_http_response UTL_HTTP.resp;

  BEGIN

  -- Make a HTTP request and get the response.

  l_http_request := UTL_HTTP.begin_request(l_url);

  l_http_response := UTL_HTTP.get_response(l_http_request);

  UTL_HTTP.end_response(l_http_response);

  END;

  /

  DECLARE

  *

  ERROR at line 1:

  ORA-29273: HTTP request failed

  ORA-06512: at "SYS.UTL_HTTP", line 1029

  ORA-24247: network access denied by access control list (ACL)

  ORA-06512: at line 7

  SQL>

  从返回的信息我们不难看出用户TEST1能够访问web页面,而用户TEST2被访问控制列表拒绝了,服务器的默认行为是拒绝访问外部网络服务,下面显示了一个新用户的测试情况。

  CONN sys/password@db11g AS SYSDBA

  CREATE USER test3 IDENTIFIED BY test3;

  GRANT CONNECT TO test3;

  GRANT EXECUTE ON UTL_HTTP TO test3;

  CONN test3/test3@db11g

  DECLARE

  l_url VARCHAR2(50) := 'http://192.168.2.3:80';

  l_http_request UTL_HTTP.req;

  l_http_response UTL_HTTP.resp;

  BEGIN

  -- Make a HTTP request and get the response.

  l_http_request := UTL_HTTP.begin_request(l_url);

  l_http_response := UTL_HTTP.get_response(l_http_request);

  UTL_HTTP.end_response(l_http_response);

  END;

  /

  DECLARE

  *

  ERROR at line 1:

  ORA-29273: HTTP request failed

  ORA-06512: at "SYS.UTL_HTTP", line 1029

  ORA-24247: network access denied by access control list (ACL)

  ORA-06512: at line 7

  SQL>

  在从10g升级到11g时,访问外部网络服务时可能会产生一些混乱,在那种情况下,你需要实现合理的访问控制列表。

  其他安全因素

  Pete Finnigan在它的博客上和关于访问控制列表的安全陈述只没有附上具体的程序包,这就意味着通过UTL_TCP, UTL_SMTP, UTL_MAIL和UTL_HTTP加上connect权限就能在服务器上打开一个端口。牢记这一点并考虑以下事项:

  ◆细粒度访问网络服务的使用不能作为忽略基本的安全评估的借口,如收回与网络服务有关程序包的不必要的权限。

  ◆通过限制对特定端口的访问控制你的服务是可用的,如果你仅仅需要访问http 80端口,指定这个端口比在服务器上开放所有端口的访问要好得多。

  ◆授权时使用通配符比不使用通配符安全性更差,也更危险。

  ◆你必须保护你的访问控制列表,如果有人能够修改它们,因为保护机制问题它们变得毫无用处,阻止直接访问存储在XML DB 数据库中的访问控制列表,确保用户不能访问管理API.

转载于:https://www.cnblogs.com/benio/archive/2010/12/03/1895357.html

Oracle11gR1中细粒度访问网络服务(转)相关推荐

  1. 虚拟机中CentOS 7 网络服务启动失败

    故障描述 虚拟机中的eth33网卡没有启动,执行systemctl status network.service启动报错 报错信息 [root@zeppelin network-scripts]# s ...

  2. VirtualBox中的虚拟网络环境设置

    网络连接其实是面向网卡的,当一台电脑拥有多块网卡,并且每块网卡连接了不同的网络就能理解了. 默认情况下,VirtualBox为虚拟网卡提供了四种网络环境:Network AddressTranslat ...

  3. 网易云网络部署参考方案-网易云网络服务研发实践|网易云

    本系列以私有云为例,将为大家讲述网易云网络服务的研发实践. 作者:张晓龙 浙江大学计算机学院本科.博士毕业.网易专业技术委员会委员.网易云计算基础设施研发负责人.专注于云计算.虚拟化.软件自定义网络( ...

  4. 携程App网络服务通道治理和性能优化

    App网络服务的高可靠和低延迟对于无线业务稳定发展至关重要,过去两年来我们一直在持续优化App网络服务的性能,到今年Q2结束时基本完成了App网络服务通道治理和性能优化的阶段性目标,特此撰文总结其中的 ...

  5. 携程App网络服务通道治理和性能优化@2016

    App网络服务的高可靠和低延迟对于无线业务稳定发展至关重要,过去两年来我们一直在持续优化App网络服务的性能,到今年Q2结束时基本完成了App网络服务通道治理和性能优化的阶段性目标,特此撰文总结其中的 ...

  6. 开发中最全网络相关内容

    iOS中网络相关内容 声明:部分图片来源于网络,有些内容也来自各个平台老师讲解的视频,部分内容来自<计算机网络>这本书中,除去参考其他博客链接外,其他部分不作出参考链接来源展示,如有相关原 ...

  7. 使用 HttpLib 来访问 Web 服务

    介绍 C# 为开发者提供很多便利方法用来访问各种 Web 服务,但是编写异步的访问方式却是有点复杂.Windows 通讯框架是一个客户端/服务器通讯非常棒的工具.我精彩发现我自己必须写很多代码来使用已 ...

  8. android 4.0下访问主进程访问网络和开启另外另外的线程

    为什么80%的码农都做不了架构师?>>>    在android 2.3上设计的下载程序,在android 4.0上运行时报android.os.NetworkOnMainThrea ...

  9. Android使用HttpURLConnection访问网络

    Android使用HttpURLConnection访问网络 一.管理网络状态 使用网络进行数据通信前,需要先获取网络状态. 使用ConnectivityManager获取网络状态步骤: 1.获取Co ...

  10. 网络服务(4)——以太网配置IP、网关

    以太网配置方法 buildroot /etc/network/interfaces 自动分配IP auto eth0 iface eth0 inet dhcp (当前使用的系统在配置了dhcp之后,如 ...

最新文章

  1. python全栈 互联网协议
  2. 纪念lxwcto(潜龙)
  3. java单线程循环调度_Java基础篇之Java线程模型
  4. cocos2d-x环境配置和常见问题
  5. 创建一个CentOS 7的模板
  6. 结合swiper使用图片懒加载
  7. python tkinterRadiobutton控件
  8. c语言二级吧,c语言二级考试
  9. 安卓频谱仪audiotool中文_频谱分析仪 TEK2712
  10. IO编程——文件复制操作
  11. 三极管与场效应管之导通与截止说明
  12. mysql translate 函数_详解Oracle中的translate函数和replace函数
  13. jAvA中deprecate,Deprecate in Java 1.6
  14. 应届毕业生2012求职之路
  15. GWT(Google Web Toolkit)初体验
  16. VSCode安装教程
  17. Centos7搭建SpringBlade的前端Saber
  18. 行业短信 运营思路_游戏行业短信平台解决方案
  19. 如何有效防治企业污染
  20. 安捷伦or是德信号源+频谱仪操作:从程控到自动测试(附A)信源播放的程控实现

热门文章

  1. Thinking in Java 11.13 Foreach与迭代器
  2. 数据结构与算法之符号表
  3. 解决IIS出现“由于权限不足而无法读取配置文件”的问题
  4. 每天一道剑指offer-翻转单词顺序列
  5. android 时间差格式化,计算2天之间的时间差android
  6. matplotlib plot 分组_Python数据分析模块二:Matplotlib
  7. scanf(%d,%d,a,b)在c语言所代表的含义,在C语言中,有语句“inta,b;scanf(a=%db=%d,a,b);”,下.._简答题试题答案...
  8. Vue源码:虚拟DOM和diff算法
  9. 实战:详解Reaact+AntD+Node后台管理系统
  10. Java直接遍历并读取zip压缩文件的内容以及错误处理