SQL Server 中的行级安全性

问题描述 投票:0回答:1

在这种情况下,我寻求帮助来为名为“user”且列为“username”和“role”的表实现行级权限。目标是建立一个安全模型,根据分配给每个用户的角色来控制对各个行的访问。具体来说,权限应遵循以下条件:当 @username=USER_NAME() 时,role='members' 只能查看 1 行,而当 @username=USER_NAME() 时,role='admins' 可以查看自己的行,并且带有角色='成员'。对于role='ceos',他们可以查看自己的行以及role='admins'的行。

CREATE FUNCTION Security.fn_securitypredicate3
         (@username AS nvarchar(50), @role AS varchar(10))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN (
    SELECT 1 AS Result
    FROM dbo.user
    WHERE 
        (@username = USER_NAME() AND @role = 'members' AND username = @username)
        OR 
        (@username = USER_NAME() AND @role = 'admins' AND (username = @username OR role = 'members'))
        OR 
        (@username = USER_NAME() AND @role = 'ceos' AND (username = @username OR role = 'admins'))
);

当我使用admin帐户登录时,我只能看到它自己的行,而看不到role='members'的行

sql-server row-level-security
1个回答
0
投票

您似乎有点困惑:

@username
@role
代表正在尝试查看的行,而函数中的
dbo.user
代表当前登录用户的行。

因此,您需要从第二个和第三个分支中删除

@username = USER_NAME()
作为谓词,并将其余部分转移到一组
OR
谓词中。

username = @username
可以作为单个谓词提升出来。这会将函数内的查询限制为当前用户的单行,因此我们可以确定他们的角色。

CREATE OR ALTER FUNCTION Security.fn_securitypredicate3
(
  @username AS nvarchar(50),
  @role AS varchar(10)
)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN

    SELECT 1 AS Result
    FROM dbo.[user] u
    WHERE u.username = @username
      AND (
         @username = USER_NAME()
         OR
         u.role = 'admins' AND @role = 'members'
         OR
         u.role = 'ceos'   AND @role = 'admins'
      )
;
© www.soinside.com 2019 - 2024. All rights reserved.