【发布时间】:2013-02-12 21:47:33
【问题描述】:
使用 Oracle VPD,在添加策略和创建函数后,我能够对未经授权的用户隐藏列。
但是我怎么能显示像'xxxxxx'这样的东西而不是(null)
同样在我验证用户登录的功能中,比如
if sys_context( 'userenv', 'session_user' ) = 'USER1'
在函数中删除这种硬编码的最佳方法是什么?
提前致谢。
【问题讨论】:
使用 Oracle VPD,在添加策略和创建函数后,我能够对未经授权的用户隐藏列。
但是我怎么能显示像'xxxxxx'这样的东西而不是(null)
同样在我验证用户登录的功能中,比如
if sys_context( 'userenv', 'session_user' ) = 'USER1'
在函数中删除这种硬编码的最佳方法是什么?
提前致谢。
【问题讨论】:
为了在非 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;
【讨论】: