VPD策略功能修改

Posted

技术标签:

【中文标题】VPD策略功能修改【英文标题】:VPD policy function Modified 【发布时间】:2018-12-17 13:37:12 【问题描述】:

您好,我昨天问了这个问题,但感谢您的帮助,我做了很多修改,所以现在我将新版本的代码放入其中,因为它变得更好但仍然无法正常工作。

假设我有一个名为payroll 的表格,由名为PCM 的用户创建

EMP_ID               DEPT                      TOTAL      TAXES
-------------------- -------------------- ---------- ----------
E1                   accounting                 2400        100 
E2                   sales                      2500         75 
E3                   research                   3000        110 
E4                   operations                 4200        120 
E5                   sales                      4800        130 
E6                   sales                      2500         75 
E7                   accounting                 5200        140 
E8                   accounting                 2700        105

现在我想要实现的是:任何拥有dept = accounting" 的人都可以使用dept != accounting 选择所有其他行,但任何拥有dept != accounting 的人都只能查看他/她的记录。

现在我作为另一个用户而不是工资表的所有者连接,所以我作为一个名为 ANNE 的用户连接:

CREATE OR REPLACE CONTEXT payroll_ctx USING payroll_ctx_pkg;
CREATE OR REPLACE PACKAGE payroll_ctx_pkg IS 
  PROCEDURE set_dept;
 END;
/
CREATE OR REPLACE PACKAGE BODY payroll_ctx_pkg IS
  PROCEDURE set_dept
  AS
    v_dept varchar2(400);
  BEGIN
     SELECT dept INTO v_dept FROM PCM.PAYROLL
        WHERE EMP_ID = SYS_CONTEXT('USERENV', 'SESSION_USER');
     DBMS_SESSION.SET_CONTEXT('payroll_ctx', 'dept', v_dept);
  EXCEPTION
   WHEN NO_DATA_FOUND THEN
   DBMS_SESSION.SET_CONTEXT('payroll_ctx', 'dept', 'NO');
  END set_dept;
END;
/

考虑到将尝试访问该表的用户具有 emp_id 列的名称,现在:

CREATE TRIGGER set_dept_trig AFTER LOGON ON DATABASE
 BEGIN
  ANNE.payroll_ctx_pkg.set_dept;
 END;
/

现在问题(我知道这是错误的)但还找不到解决方案:

CREATE OR REPLACE PACKAGE security_package AS 
FUNCTION sec_fun (D1 VARCHAR2, D2 VARCHAR2) 
RETURN VARCHAR2; 
END;
/
CREATE OR REPLACE PACKAGE BODY security_package AS 
FUNCTION sec_fun (D1 VARCHAR2, D2 VARCHAR2) 
RETURN VARCHAR2
IS
    vv_dept varchar2(400);
    V_ID varchar2(400);
begin
    V_ID := SYS_CONTEXT('USERENV', 'SESSION_USER');
    vv_dept := 'SYS_CONTEXT(''payroll_ctx'', ''dept'')';
    if (vv_dept != 'accounting') then
    RETURN 'EMP_ID = ' || CHR(39)||V_ID||CHR(39);
    ELSE
    RETURN 'DEPT != ' || CHR(39)||vv_dept||CHR(39);
  END IF;
    EXCEPTION
  WHEN NO_DATA_FOUND
  THEN
    RETURN '1 = 0';
end sec_fun;
end security_package;
/

最后:

BEGIN
 DBMS_RLS.ADD_POLICY (
  object_schema    => 'PCM', 
  object_name      => 'PAYROLL', 
  policy_name      => 'payroll_policy', 
  function_schema  => 'ANNE',
  policy_function  => 'security_package.sec_fun',
  statement_types  => 'select');
END;
/

现在,当用户 E1 尝试从工资单中进行选择时,输出为:

EMP_ID               DEPT                      TOTAL      TAXES
-------------------- -------------------- ---------- ----------
E1                   accounting                 2400        100 

我做错了什么??它应该返回 dept != accounting

的所有行

【问题讨论】:

我认为您在 sec_fun 函数中的意思是 v_id := SYS_CONTEXT('USERENV', 'SESSION_USER');,而不是 v_id := user;。无论如何,这就是您在 set_dept 过程中的谓词中使用的来查找特定 emp_id 的部门 是的,我也试过了,但结果一样,还有其他建议吗?? 如果你自己运行security_package.sec_fun函数,你得到的输出是什么? 我做了以下修改:vv_dept := 'SYS_CONTEXT(''payroll_ctx'', ''dept'')'; 现在当我运行 security_package.sec_fun 如下:select security_package.sec_fun('PCM','payroll') from dual; 输出是:EMP_ID = 'ANNE' 现在当 E1 写语句时:select * from PCM.payroll; 只返回他的行,这仍然是错误的。 【参考方案1】:

感谢您的帮助,我终于设法解决了这个问题,当我进行以下修改时,它位于变量 vv_dept 中:

CREATE OR REPLACE PACKAGE security_package AS 
FUNCTION sec_fun (D1 VARCHAR2, D2 VARCHAR2) 
RETURN VARCHAR2; 
END;
/
CREATE OR REPLACE PACKAGE BODY security_package AS 
FUNCTION sec_fun (D1 VARCHAR2, D2 VARCHAR2) 
RETURN VARCHAR2
IS
    V_ID varchar2(400);
begin
    V_ID := SYS_CONTEXT('USERENV', 'SESSION_USER');
    if (SYS_CONTEXT('payroll_ctx','dept') = 'accounting') then
    RETURN 'DEPT != ' || CHR(39)||SYS_CONTEXT('payroll_ctx','dept')||CHR(39);
    ELSE
        RETURN 'EMP_ID = ' || CHR(39)||V_ID||CHR(39);
  END IF;
    EXCEPTION
  WHEN NO_DATA_FOUND
  THEN
    RETURN '1 = 0';
end sec_fun;
end security_package;
/

【讨论】:

以上是关于VPD策略功能修改的主要内容,如果未能解决你的问题,请参考以下文章

EBS VPD介绍和使用实例

关于android audio路由策略的修改(续)

修改组策略时,提示“未能保存本地策略数据库”?

域控制器组策略密码策略被锁定,如何解决?

OpenLDAP 密码策略(转载)

如何在 Linux 上设置密码策略