【问题标题】:Row-Level Security Predicate Filter行级安全谓词过滤器
【发布时间】:2021-06-11 09:03:08
【问题描述】:

在 Oracle 19c 上。

我们的用户的帐户是通过指定逗号分隔的department_code 值列表来配置的。每个department_code 值都是由五个字母数字 [A-Z0-9] 字符组成的字符串。这个由五个字符department_codes 组成的逗号分隔值列表就是我们所说的用户的security_string。我们使用这个security_string 来限制用户可以从表Restricted 中检索哪些行,方法是应用以下谓词。

select *
from Restricted R
where :security_string like '%' || R.department_code || '%';

给定的department_code 可以多次出现在Restricted 中,并且给定的用户可以在其逗号分隔值:security_string 中拥有多个department_code

这种应用行级安全性的谓词方法效率低下。不能使用索引,它需要对Restricted 进行全表扫描。

另一种方法是使用动态 SQL 执行如下操作。

execute immediate 'select *
from Restricted R
where R.department_code in(' || udf_quoted_values(:security_string) || ')';

其中udf_quoted_values 是一个用户定义函数 (UDF),它将 :security_string 中的每个 department_code 值括在单引号中。 但是,这种替代方法似乎也不能令人满意,因为它需要 UDF、动态 sql,并且仍然可能进行全表扫描。

我考虑过位掩码,但所需的位数是 6000 万 (=36^5),它仍然需要 UDF、动态 sql 和全表扫描(基于函数的索引不需要似乎是这里的候选人)。此外,位掩码在这里没有多大意义,因为department_codes 没有嵌套/层次结构。

execute immediate 'select *
from Restricted R
where BITAND(R.department_code_encoded,' || udf_encoded_number(:security_string) || ') > 0';

其中Restricted.department_code_encodedRestricted.department_code 的数字编码值,udf_encoded_number 是一个用户定义的函数 (UDF),它返回一个编码 department_codes 的数字 :security_string

我考虑过创建一个仅包含部门代码的单独表 Department,并将其加入到 Restricted 表中。

select *
from Restricted R
join Department D
on R.deparment_code = D.department_code
where :security_string like '%' || D.department_code || '%';

我们仍然遇到与以前相同的问题,但现在它在较小的(表基数)Department 表上(Department.department_code 是唯一的,而 Restricted.department_code 不是唯一的)。这为Department 提供了比Restricted 更小的全表扫描,但现在我们有了一个连接。

在配置帐户时,我们可以更改security_string 或添加其他用户特定的安全值。我们还可以更改 Oracle 对象和查询。请注意,department_codes 不是静态的,但也不要定期更改。

有什么建议吗?提前谢谢你。

【问题讨论】:

    标签: sql oracle csv sql-like row-level-security


    【解决方案1】:

    为什么不将字符串转换为表格,如建议的here,然后进行连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 2015-07-22
      • 1970-01-01
      • 2021-10-19
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多