【问题标题】:Row Level Security with multiple users for one row一行有多个用户的行级安全性
【发布时间】:2017-10-02 15:41:05
【问题描述】:

我正在尝试在 SQL Server 2016 中实现行级安全性。

问题是,我可以有多个用户应该对给定的行具有读取权限,当我在谓词中编写一些复杂的条件时,性能变得非常非常非常糟糕。

我尝试将所有用户名保留在表的一列和谓词中,以通过它们搜索 SYSTEM_USER% LIKE %,但性能很低。

我的受控表中用户名列中一行的值示例:

domain\john.wick;domain\red.eagle;domain\spartak.something....

这是我的功能:

CREATE FUNCTION fn_securitypredicate(@Usernames AS nvarchar(4000))  
  RETURNS TABLE  
WITH SCHEMABINDING  
AS  
  RETURN
  SELECT 1 as Result
  WHERE @Usernames LIKE '%' + SYSTEM_USER + '%'

执行时间从 2 秒变为 50 秒。任何改进建议。

CREATE SECURITY POLICY [Policy]   
ADD FILTER PREDICATE [fn_securitypredicate]([Usernames])   
ON [dbo].[Products];  

【问题讨论】:

  • 1.请在此处发布您的代码 2. 使用 %...% 可以实现什么性能?为什么不搜索完全匹配?
  • 我添加了更多细节和代码。
  • 好吧,我的问题仍然存在,你为什么不使用完全匹配? WHERE @Usernames=SYSTEM_USER'
  • 因为每一行有多个用户,我不能使用精确匹配....否则这将是最优化的解决方案。我给出的例子是一行,“;”用户名列中每一行的分隔值
  • 如果你想加速你的代码,你应该规范化你的表。当行中只有一个用户时,可以使用索引。当您使用具有多个用户的行并且喜欢 %...% 时,没有索引可以帮助您。您可以将您的用户分组到角色/Windows 组中,并且每行有一个角色/组吗?

标签: sql sql-server row-level-security security-policy


【解决方案1】:

这是我为以前的团队提出的解决方案。

这需要用户表、用户权限表以及受控表上的权限列。它还应该有一个用户组和用户组权限表以随用户扩展。

users                   user_permissions            controlled_table
+-----------+---------+ +---------+---------------+ +---------------+------+------+
| user_name | user_id | | user_id | permission_id | | permission_id | pk_1 | pk_2 |
+-----------+---------+ +---------+---------------+ +---------------+------+------+
| admin     |       1 | |       1 |             0 | |             2 |    1 |    1 |
| user1     |       2 | |       2 |             1 | |             2 |    1 |    2 |
| user2     |       3 | |       2 |             2 | |             3 |    1 |    3 |
| user3     |       4 | |       2 |             3 | |             4 |    2 |    1 |
|           |         | |       2 |             4 | |             3 |    2 |    2 |
|           |         | |       3 |             1 | |             1 |    2 |    3 |
|           |         | |       3 |             2 | |             1 |    3 |    1 |
|           |         | |       4 |             2 | |             5 |    3 |    2 |
|           |         | |       4 |             3 | |             4 |    3 |    3 |
|           |         | |       4 |             4 | |             2 |    4 |    1 |
|           |         | |         |               | |             3 |    4 |    2 |
|           |         | |         |               | |             3 |    4 |    3 |
+-----------+---------+ +---------+---------------+ +---------------+------+------+

为了提高性能,您需要将 permission_id 添加到您用于搜索受控表的任何索引中。这将允许您在搜索剩余列时加入索引权限。您应该查看执行计划以了解有关索引的具体详细信息。

【讨论】:

  • 是的,但这意味着受控表中的每一行都会在其他表上进行选择。这就像做 INNER JOIN。它太慢了这个过程。在我使用的存储过程中,有很多聚合,如果该过程的正常执行时间是 2 秒,按照您建议的方式,它变成了 3 分 50 秒 ...
猜你喜欢
  • 1970-01-01
  • 2013-01-18
  • 2018-02-03
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
  • 2018-09-23
  • 2019-09-07
相关资源
最近更新 更多