一行有多个用户的行级安全性
Row Level Security with multiple users for one row
我正在尝试在 SQL Server 2016 中实施行级安全性。
问题是,我可以有多个用户应该对给定的行具有读取权限,当我在谓词中写入一些复杂的条件时,性能会变得非常非常非常糟糕。
我试图将所有用户名保留在 table 的一列中,并在谓词中搜索 SYSTEM_USER
和 % LIKE %
但性能很低。
我控制的 table 中用户名列中一行值的示例:
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];
这是我为我以前的团队想出的解决方案。
这需要一个用户 table、一个用户权限 table 以及您控制的权限列 table。它还应具有用户组和用户组权限 table 以随用户扩展。
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 添加到您用于搜索受控 table 的任何索引中。这将允许您在搜索其余列时加入对索引的权限。您应该查看执行计划以了解有关索引的具体详细信息。
我正在尝试在 SQL Server 2016 中实施行级安全性。
问题是,我可以有多个用户应该对给定的行具有读取权限,当我在谓词中写入一些复杂的条件时,性能会变得非常非常非常糟糕。
我试图将所有用户名保留在 table 的一列中,并在谓词中搜索 SYSTEM_USER
和 % LIKE %
但性能很低。
我控制的 table 中用户名列中一行值的示例:
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];
这是我为我以前的团队想出的解决方案。
这需要一个用户 table、一个用户权限 table 以及您控制的权限列 table。它还应具有用户组和用户组权限 table 以随用户扩展。
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 添加到您用于搜索受控 table 的任何索引中。这将允许您在搜索其余列时加入对索引的权限。您应该查看执行计划以了解有关索引的具体详细信息。