oracle数据库:Oracle 10g 新特性的虚拟专用数据库

="t18">
   5种类型策略、列相关策略以及列屏蔽使得 VPD 成为 DBA 安全工具箱中种功能更加强大工具
  
  虚拟专用数据库 (VPD) 也称为细粒度访问控制它提供强大行级安全功能它是在 Oracle8i 中推出已经受到广泛欢迎并且在从教育软件Software到金融服务等各种应用得到采用
  
  VPD 工作思路方法是通过透明地更改对数据请求基于系列定义标准向用户提供表局部视图在运行时所有查询都附加了谓词以便筛选出准许用户看到例如假如只答应用户查看帐户治理员 SCOTT 帐户则 VPD 设置自动地将查询:
  
  select * from accounts;
  
  重写为:
  
  select * from accounts
  where am_name = 'SCOTT';
  
  DBA 在表 ACCOUNTS 上设置了项安全策略该策略具有个相关称为policy function它返回个用作谓词串 where am_name = 'SCOTT'假如您不熟悉该特性全部功能我建议您阅读 Oracle 杂志文章“利用 VPD 保持信息私密性”
  
  策略类型

  生成谓词所需重复分析是种在某些情况下可以进行修整开销例如在大部分实际情况中谓词并不象 am_name = 'SCOTT' 那样是静态;它基于用户身份、用户权限级别、用户向哪个帐户治理员进行报告等情况,可能更具有动态性由策略创建并返回串可能会具有很强动态性而为了保证其结果Oracle 必须每次重新执行策略既浪费资源又降低性能在这种类型策略中谓词每次执行时可能会有很大差别该策略称为“动态”策略在 Oracle9i 数据库以及以前版本中已经提供了这种策略
  
  除了保留动态策略的外Oracle 数据库 10g 还基于谓词构造推出了几种新类型策略为提高性能提供了更好控制:context_sensitive、shared_context_sensitive、shared_现在让我们来了解每种策略类型意义以及如何在适当场合中使用它们
  
  动态策略 为保持向后兼容性10g 中默认策略类型为“dynamic” — 正如 Oracle9i 中在这种情况下对于每行以及每位用户在每次访问表时都对策略进行重新求值让我们来具体分析策略谓词:

  where am_name = 'SCOTT'
  
  忽略掉 where 子句谓词就具有两个区别部分:在等式操作符的前部分 (am_name) 和等式操作符的后部分 ('SCOTT')在大多数情况下后面部分更象是变量它是由用户数据提供(假如用户是 SCOTT则其值为 'SCOTT')在等号前面部分是静态因此即使不必为生成适当谓词而对每行求出策略由于了解前面部分静态性以及后面部分动态性也可以提高性能在 10g 中可以在 dbms_rls.add_policy 中使用 "context_sensitive" 类型策略作为参数来实现这种思路方法:

  policy_type => dbms_rls.context_sensitive
  
  在另个举例中我们有个称为 ACCOUNTS 它拥有几列其中列是 BALANCE表示帐户余额假设答应某个用户查看低于某特定余额帐户而该余额由应用上下文所决定我们并不在策略中将此余额值固定而是3是根据应用上下文确定如:

  create or replace vpd_pol_func
  (
  p_schema in varchar2,
  p_table in varchar2
  )
   varchar2
  is
  begin
   'balance < sys_context(''vpdctx'', ''maxbal'')';
  end;
  
  应用上下文 VPDCTX 属性 MAXBAL 可以在会话前期设定在运行时可以轻易地获得该数值
  
  请仔细注重该举例谓词有两部分:小于号的前部分和的后部分的前部分是“balance”它是文后面部分从某种程度而言是静态应用上下文变量在改变的前直是常量假如应用上下文属性不变则整个谓词是常量因此不需要重新执行假如策略类型定义为对上下文敏感则 Oracle 数据库 10g 可以识别此情况以用于优化假如在会话期间没有发生会话上下文变化则不重新执行该从而显著提高了性能
  
  静态策略 有时业务操作可以确保谓词更加静态例如在上下文敏感策略类型举例中我们将用户所见最大余额定义为个变量当 web 应用 Oracle userid 由许多 web 用户共享并且应用基于这些用户权限来设置该变量(应用上下文)时这种思路方法很有用因此web 用户 TAO 和 KARTHIK 都是以用户 APPUSER 连接到数据库 2者可以在其会话中拥有两个区别应用上下文此时 MAXBAL 值并不依靠于 Oracle userid而是依靠 TAO 和 KARTHIK 各自会话
  
  在静态策略情况下谓词更具有可猜测性其介绍说明如下

  
  LORA 和 MICHELLE 分别是 Acme Bearings 和 Goldtone Bearings 帐户治理员当他们连接数据库时他们使用自己 id并且只应该看到属于他们那些行在 Lora 方面谓词变成 where CUST_NAME = 'ACME';而对于 Michelle则是 where CUST_NAME = 'GOLDTONE'在这里谓词依靠于他们 userid因此他们所创建任何会话在应用上下文中始终具有相同
  
  10g 可以利用这种情况在 SGA 中对谓词进行高速缓存Cache并在会话中重用该谓词而不必重新执行策略策略类似于以下形式:
  
  create or replace vpd_pol_func
  (
  p_schema in varchar2,
  p_table in varchar2
  )
   varchar2
  is
  begin
   'cust_name = sys_context(''vpdctx'', ''cust_name'')';
  end;
  
  而策略定义为:
  
  policy_type => dbms_rls.
  
  这种思路方法确保策略只执行即使应用上下文在会话中改变也从不重新执行该使得此过程速度非常快
  
  建议将静态策略用于在几个用户中托管应用情况在这种情况下单个数据库拥有几个用户数据当每个用户登录时登录后触发器可以设置用于策略应用上下文以便快速生成谓词
  
  但是将策略定义为静态也是把双刃剑在以上举例中我们假设应用上下文属性 VPDCTX.CUST_NAME 值在会话中不改变假如这种假设不正确将会怎样呢?假如该值改变策略将不会执行因此在谓词中将不会使用新值而返回结果!因此在将策略定义为静态时要非常小心;您必须绝对确信该值不会改变假如您不能作这种假设则最好将策略定义为对上下文敏感
  
  共享策略类型 为了重用代码并最大限度地利用已经分析过代码您可以决定为几个表使用通用策略例如在上述举例中我们可能对于区别类型帐户拥有区别表 — SAVINGS 和 CHECKING — 但是规则仍然是相同:限制用户查看余额超过其授权范围帐户这种情况要求为 CHECKING 和 SAVINGS 表上策略使用统该策略创建为 context_sensitive
  
  假设事件按如下顺序发生:
  
  1. 连接会话
  2. 设置应用上下文
  3. select * from savings;
  4. select * from checking;
  
  即使应用上下文在第 3 步和第 4 步的间没有改变策略也会重新执行现在所选择表已经区别这不是我们所希望情况策略相同不需要重新执行该
  
  10g 中新功能是能够在对象间共享策略在上述举例中您可以将这些策略策略类型定义为:
  policy_type => dbms_rls.shared_context_sensitive
  
  将策略声明为 "shared" 可以在以上所示情况中不再执行该从而提高了性能
  
  选择性

  现在设想种情况只有在选择了特定列时才会应用 VPD 策略在上述举例表 ACCOUNTS 中各行如下所示:

  ACCTNO ACCT_NAME  BALANCE
  ------ ------------ -------
  1 BILL CAMP  1000
  2 TOM CONNOPHY 2000
  3 ISRAEL D   1500  
  
  不答应 Michelle 查看余额超过 1600 帐户当她执行类似以下查询时:

  select * from accounts;
  
  将看到:

  ACCTNO ACCT_NAME  BALANCE
  ------ ------------ -------
  1 BILL CAMP  1000
  3 ISRAEL D   1500  
  
  acctno 2 余额超过 1600它已禁止显示对于 Michelle 而言表中只有两行而不是 3行当她执行类似以下查询时:
  select count(*) from accounts;
  
  该查询只计算表中记录数输出是 2而不是 3

  但是此时我们可以决定将安全策略稍微放松在本查询中Michelle 不能查看帐户余额等秘密数据;她只是计算表中所有记录数目在和安全策略情况下我们可以答应此查询计算所有记录数目无论是否答应她查看这些记录假如需要这样则在对 10g dbms_rls.add_policy 个参数答应实现此功能:
  
  sec_relevant_cols => 'BALANCE'
  
  现在当用户选择列 BALANCE 时无论是显式选择还是隐含在 select * 中VPD 策略都会介入对行作出限制否则将会选择表中所有在查询中用户只选择了总计行数而没有选择列 BALANCE假如将以上参数设置为所示形式则查询

  select count(*) from accounts;
  
  将显示 3列而不是两列但是查询:

  select * from accounts;
Tags:  oracle删除数据库 oracle数据库备份 oracle创建数据库 oracle数据库

延伸阅读

最新评论

发表评论