你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Linux开发
oracle 基础(18)
 

问题
主要有以下四个问题:

  1. 当选择做出之后如果处理器模块(如果定义了)抛出错误,将会在 Oracle 不同版本中引起不同的行为:
    • 在 Oracle9i 数据库中,处理器模块 以无提示的方式 停止对该行进行检索,不会报错。 因此,如果有 100 行,其中 4 行满足了审计条件,处理器模块运行四次,每次都会失败。 该查询将仅仅返回 96 行,而不报告任何错误,您将绝不会知道事情已经发生了。 很显然,这种做法会产生不精确的结果。
    • 在 Oracle Database 10g 第 1 版中,处理器模块将忽略处理器模块中的错误,按照预期检索所有 100 行。
    • 在 Oracle Database 10g 第 2 版中,处理器模块将报告执行查询的用户会话方面的错误,而不返回任何行,甚至不返回那些不满足审计条件而没有执行处理器函数的 96 行。

    所以,在实施 FGA 处理器模块之前请先对其进行全面测试。

  2. 审计线索表——FGA_LOG$——在系统表空间中。 当更多的 FGA 条目产生时,空间表就填满了,这可能导致数据库运行中断。

  3. 审计线索被写入表中,不过是以异步方式进行的。 这会产生事务处理和 I/O,它将增加到数据库中的整体 I/O 中。 如果您的数据库是受 I/O 所限,您将看到实施 FGA 处理器模块后对整个数据库的性能影响。

  4. 您可以使用自治事务处理以异步方式编写审计线索。 所以,即使用户回滚该事物处理,也不会删除该线索条目,导致错误的正值. 如果您想将 FGA 用作一种简单的机制来识别用户,您应该注意这些错误的正值。

操作清单

  1. 识别敏感的表和列。
  2. 识别要访问的敏感度——例如,工资低于 500 的。
  3. 将所有可能的组合放在一张纸上,然后将这些组合合并成 WHERE 条件(谓词),在这种方式下,只要一个谓词就将满足任何给定的条件。
  4. 在那些谓词中构建 FGA 策略。
  5. 启动 FGA 策略。
  6. 之后,分析 FGA 审计线索文件。
  7. 制作清除计划,清除 FGA 线索表。

4.2 激活虚拟专用数据库

背景
如果您已经很熟悉应用程序环境和虚拟专用数据库(也称为行级安全性或细粒度访问控制),您可以跳过该节,直接查看策略节。

虚拟专用数据库 (VPD) 是一个很大的主题,因此我在这里只将一些基本的。 要了解背景知识,请参考我的 Oracle 杂志中有关该主题的 文章;您也可以在我的书里面找到关于 FGA 方面的更多信息。

假设您有一个称为 ACCOUNTS 的表,表中有以下数据:

SQL> select * from rates;

     ACCNO ACC_NAME                ACC_BAL
---------- -------------------- ----------
         1 John                       1000
         2 Jill                       1500
         3 Joe                        1200
         4 Jack                       1300
您想确保只有得到适当授权的人才可以查阅授权范围的帐户余额。也就是说,级别 1 看到的余额应该小于 1,000,级别 2 看到的余额应该小于 1,200,级别 3 可以看到所有的余额。 您还有另一张显示用户和级别的表。
SQL> select * from tab;

USERNAME                        USERLEVEL
------------------------------ ----------
CLERK1                                  1
CLERK2                                  2
CLERK3                                  3
要存储用户首次登录时的用户级别,因此需要创建应用程序环境:
create context user_level_ctx using set_user_level_ctx;
以及相关的可信过程:
create or replace procedure set_user_level_ctx
(
    p_level in number
)
as
begin
    dbms_session.set_context (
            'USER_LEVEL_CTX',
            'LEVEL',
            p_level
    );
end;
接着,您需要创建登录触发器以设置适当的应用程序环境。
create or replace trigger tr_set_user_level
after logon
on database
declare
   l_level number;
begin
   select userlevel
   into l_level
   from arup.userlevels
   where username = user;
   set_user_level_ctx (l_level);
exception
   when NO_DATA_FOUND then
null;
   when OTHERS then
        raise;
end;
这设置了一个阶段,您可以按照该阶段在应用程序环境属性设置用户级别。 我们测试一下,以确保:
SQL> conn clerk1/clerk1
Connected.
SQL> select sys_context('USER_LEVEL_CTX','LEVEL') from dual;

SYS_CONTEXT('USER_LEVEL_CTX','LEVEL')
--------------------------------------
1

SQL> conn clerk2/clerk2
Connected.
SQL> select sys_context('USER_LEVEL_CTX','LEVEL') from dual;

SYS_CONTEXT('USER_LEVEL_CTX','LEVEL')
--------------------------------------
2

SQL> conn clerk3/clerk3
Connected.
SQL> select sys_context('USER_LEVEL_CTX','LEVEL') from dual;

SYS_CONTEXT('USER_LEVEL_CTX','LEVEL')
--------------------------------------
3

正如您可以看到的,每个用户 ID 都设置了相应的级别。 现在,您可以在表上构建 VPD。 您可以使用所提供的 PL/SQL 包 DBMS_RLS 控制整个 VPD 基础架构;一个称为策略的概念控制着决定应该显示哪些行的规则。 策略将“谓词”(WHERE 条件)应用到表中的所有查询上,有效地限制了对行的访问。 一个称为策略函数的函数生成 WHERE 条件。 因此,首先我们必须创建策略函数,该函数返回 WHERE 条件以将该条件应用到查询中。

create or replace function get_acc_max_bal
(
p_schema in varchar2,
   p_obj           in varchar2
)
return varchar2
as
   l_ret   varchar2(2000);
begin
select
           case userlevel
                   when 1 then 'acc_bal <= 1000'
                   when 2 then 'acc_bal <= 1200'
                   when 3 then null
else
                   '1=2'
end
   into l_ret
   from userlevels
where username = 'HR'
   return l_ret;
end;
然后添加策略:
begin
   dbms_rls.add_policy (
object_name => 'EMP',
policy_name => 'ACCOUNTS_ACCESS',
policy_function => 'USER_ONLY',
          statement_types      => 'INSERT, UPDATE, DELETE, SELECT',
          update_check         => TRUE
          );
end;
这次表得到保护。 当 CLERK1 登录并从表中进行选择:
SQL> select * from arup.accounts;

     ACCNO ACC_NAME                ACC_BAL
---------- -------------------- ----------
         1 John                       1000
Clerk1 只能看到 ACCNO 1,余额为 1,000。因为没有授予 Clerk1 查看高于 1,000 的账户余额,所以他看不到其它账户。 但是,当 Clerk2 登录时:
SQL> conn clerk2/clerk2
Connected.
SQL> select * from arup.accounts;

     ACCNO ACC_NAME                ACC_BAL
---------- -------------------- ----------
         1 John                       1000
         2 Joe                        1200

她也可以看到 ACCNO 2。 ACCNO 2 的余额为 1,200,在给 Clerk2 的授权限制之内。

您可以使用该技术将被限制的视图类放到表中。 在项目锁定中,这将是一个很方便的工具。

策略
关键是找出各方面的哪些信息将被保护,哪些列上的信息将被保护。 这听起来很简单,但是实际做起来是很难的。 收集该信息需要商业知识,或者合作者至少要更熟悉那些过程。 一旦您识别到表和列,您应该能够按照以上背景部分中示例中显示的那样实施 VPD 策略。

即使 VPD 是很效的,如果您想让一些用户可以不受限制就可以访问表怎么办? 角色 EXEMPT ACCESS POLICY 的确是这样做的。

grant exempt access policy to ananda;

从此处开始,ANANDA 将跳过在所有表中定义的所有访问策略。

使用户跳过所有访问限制可能是不可接受的,然而,一个更好的解决方案是在策略函数中对其进行编码。 一个很好的示例就是表的模式所有者——无疑您想该所有者看到表的所有行而不受到限制。 您可以在策略函数中对其进行如下编码:

create or replace function get_acc_max_bal
(
p_schema in varchar2,
   p_obj           in varchar2
)
return varchar2
as
   l_ret   varchar2(2000);
begin
   if (p_schema = USER) then
           l_ret := NULL;
else
select
                   case userlevel
                           when 1 then 'acc_bal <= 1000'
                           when 2 then 'acc_bal <= 1200'
                           when 3 then null
else
                           '1=2'
end
           into l_ret
           from userlevels
where username = 'HR'
end if;
   return l_ret;
end;

当表的所有者登录 (p_schema = USER) 时,该版本函数返回 NULL,所以对表的访问不受限制。 当然,您可以在该函数中进行任意更改,以允许更多用户跳过 VPD 策略。

VPD 的最大挑战是对子表进行限制。 您的限制条件可能在称为 ACC_BAL 的列上;但是所有其它子表不可能有该列。 因此,您如何限制那些表?

例如,这里有一个称为地址的表,该表包含这些客户的地址。 该表没有称为 ACC_BAL 的列,因此您如何对该表设置和 ACCOUNTS 表一样的限制? 有如下两种方式:

  • 将列 ACC_BAL 添加到地址表中。 您可以通过主表 ACCOUNTS 中的触发器对该列进行更新。 现在,您可以使用 ACCOUNTS 上使用的相同策略函数定义表中的策略。

  • 对 ADDRESSES 表使用不同的策略函数。 在该函数中,返回值应该是
    ACCNO in (SELECT ACCNO FROM ACCOUNTS)

    这是策略限制中使用的谓词。 因此,VPD 将只显示表上的账户地址。而且因为无论如何 VPD 限制了表 ACCOUNTS,所以 VPD 将自动限制表 ADDRESSES。

您必须按照自己所处的环境从这两种方法中选取一种。

(编辑:aniston)

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089