【问题标题】:Oracle VPD column masking, how can I change the default (null) value to XXXOracle VPD 列屏蔽,如何将默认(空)值更改为 XXX
【发布时间】:2013-02-12 21:47:33
【问题描述】:

使用 Oracle VPD,在添加策略和创建函数后,我能够对未经授权的用户隐藏列。

但是我怎么能显示像'xxxxxx'这样的东西而不是(null)

同样在我验证用户登录的功能中,比如

if sys_context( 'userenv', 'session_user' ) = 'USER1'

在函数中删除这种硬编码的最佳方法是什么?

提前致谢。

【问题讨论】:

    标签: oracle oracle10g


    【解决方案1】:

    为了在非 null 的位置返回文本,您必须在表格顶部创建一个视图,以将 null 更改为您想要的静态文字,因为 VPD 中的唯一选项是隐藏行或将机密列设置为 NULL。

    对于您问题的第二部分,如果您使用该检查来确定谁有权访问敏感列,您可以改用角色并让 VPD 功能检查如下:

    return 'exists (select null from session_roles where role = ''XXXXXX'')';
    

    即在其会话中设置角色XXXXXX(只需创建适当的角色并将其授予您的特权用户)的任何人都可以看到数据。这样你就不需要硬编码一堆用户 ID。

    例如:

    如果我们创建一个角色并将其授予测试用户:

    SQL> create role ACCESS_TABLEA_SEC_COL;
    
    Role created.
    
    SQL> grant ACCESS_TABLEA_SEC_COL to test;
    
    Grant succeeded.
    

    对于我的设置,我创建了一个简单的测试表 + 一个阻止人们阅读 your_sec_col 列的策略。

    SQL> create or replace package pkg_security_control
      2  as
      3    function apply_access(p_owner in varchar2, p_obj_name  in  varchar2) return varchar2;
      4  end;
      5  /
    
    Package created.
    
    SQL> create or replace package body pkg_security_control
      2  as
      3    function apply_access(p_owner in varchar2, p_obj_name  in  varchar2)
      4      return varchar2
      5    is
      6    begin
      7      return 'exists (select null from session_roles where role = ''ACCESS_TABLEA_SEC_COL'')';
      8    end;
      9  end;
     10  /
    
    Package body created.
    
    SQL> create table TABLEA
      2  (
      3    id number primary key,
      4   your_sec_col  varchar2(30)
      5  );
    
    Table created.
    
    SQL> insert into tablea values (1, 'secret text1');
    
    1 row created.
    
    SQL> insert into tablea values (2, 'secret text2');
    
    1 row created.
    

    现在,如果我们从该表中选择并且我们没有 ACCESS_TABLEA_SEC_COL 角色,我们会得到:

    SQL> select *
      2    from tablea;
    
            ID YOUR_SEC_COL
    ---------- ------------------------------
             1
             2
    

    但是你想要一个像xxxxx 这样的字符串。 VPD 本身无法做到这一点,但视图可以将NULL 解码为该字符串。

    SQL> create view v_tablea
      2  as
      3  select id, case when your_sec_col is null then 'xxxxxx' else your_sec_col end your_sec_col
      4    from TABLEA;
    
    View created.
    

    现在从视图中选择将取决于是否设置了角色:

    SQL> set role none;
    
    Role set.
    
    SQL> select *
      2    from tablea;
    
            ID YOUR_SEC_COL
    ---------- ------------------------------
             1
             2
    
    SQL> select *
      2    from v_tablea;
    
            ID YOUR_SEC_COL
    ---------- ------------------------------
             1 xxxxxx
             2 xxxxxx
    
    SQL> set role all;
    
    Role set.
    
    SQL> select *
      2    from v_tablea;
    
            ID YOUR_SEC_COL
    ---------- ------------------------------
             1 secret text1
             2 secret text2
    
    SQL> select *
      2    from tablea;
    
            ID YOUR_SEC_COL
    ---------- ------------------------------
             1 secret text1
             2 secret text2
    

    因此,VPD 仍会保护您的表免受任何人从中选择,但您需要让客户端从视图中选择以获取文字字符串。如果您的受保护字符串可以包含 NULL,并且您希望将它们与无访问权限区分开来,则可以将角色检查放在视图中。

    create view v_tablea
    as
    select id, 
           case (select 'A' from session_roles where role = 'ACCESS_TABLEA_SEC_COL') 
             when 'A' then your_sec_col else 'xxxxxxxx' end your_sec_col
      from TABLEA;
    

    【讨论】:

    • 视图将不会根据登录用户而改变,一旦创建,但在这里取决于登录用户,我必须显示实际列值或显示“xxxxx”。你能澄清一下你的方法吗?例如,在所有情况下触发的查询将是...select * from emp;
    • @Hemal 是的,我很快就会用一个测试用例来编辑它。是的,视图不需要更改,我们只需要一个视图来显示“xxxxx”而不是 NULL(因为 VPD 除了显示 NULL 或删除行之外什么都不支持)。
    猜你喜欢
    • 1970-01-01
    • 2020-12-09
    • 2022-12-04
    • 2017-07-01
    • 2012-07-03
    • 2013-04-15
    • 2014-11-06
    • 2021-07-17
    相关资源
    最近更新 更多