【问题标题】:SQLServer, temporarily disabling row level securitySQLServer,暂时禁用行级安全性
【发布时间】:2018-08-14 09:26:00
【问题描述】:

我在 SQLServer 中的 Person 表中实现了行级安全性(以满足 GDPR 要求),因此基本用户只能看到个人记录的子集。这 人员表有一些数据(RFID 标签)在系统中必须是唯一的。所以我的应用程序检查没有重复的 RFIDtag。

当 RLS 开启时如何做这个检查,因为查询只看到行的子集,但 RFID 必须是全局唯一的?在暂时禁用 RLS 的情况下运行此查询的最佳方法是什么?

我的第一个想法是使用存储函数来执行检查。作为“sa”用户 sa 执行的函数可以看到所有行。还有其他(更简单)的想法吗?

【问题讨论】:

  • 永远不需要在数据库中以sa 的身份执行。 EXECUTE AS 是这里的解决方案,但您最好作为仅具有所需权限的特定用户(CREATE USER ... WITHOUT LOGIN)这样做。
  • 也许我想得太简单了,但UNIQUE 索引不会也能处理好事情吗?您可以捕获重复错误以向用户呈现更有意义的错误消息。作为奖励,这也比插入前检查模式更安全。

标签: sql-server row-level-security


【解决方案1】:

UNIQUE 索引是最安全的方法,就像@Jeroen 的评论中所说的那样。

不过,在其他情况下可能需要禁用行级安全性。需要时,我的建议是:

  • 为此创建一个“管理员”用户 (CREATE USER admin WITHOUT LOGIN;)

在你的验证函数中包含逻辑来解释这个用户:

CREATE FUNCTION Security.fn_securitypredicate(@param as VARCHAR(100))  
RETURNS TABLE  
WITH SCHEMABINDING  
AS  
    RETURN SELECT 1 AS Result
    WHERE
        /* Your logic here */ 
        OR
        USER_NAME() = 'admin' ;

这样,当您冒充“管理员”用户时,所有记录都可以访问。任何其他用户,您的行级安全逻辑仍然适用。

在运行查询时模拟用户:

EXECUTE AS USER = 'admin';
SELECT * FROM MyTable;
REVERT; -- Returns to the original user context

【讨论】:

  • UNIQUE 索引可能是这里最好的方法,因为我不能冒充“管理员”工作。如果用户 admin 具有在没有 RLS 的情况下进行查询的必要权限,则基本用户无法以 admin 身份执行!
猜你喜欢
  • 1970-01-01
  • 2011-06-29
  • 1970-01-01
  • 2019-03-30
  • 2021-10-12
  • 2022-10-05
  • 2018-09-23
  • 2021-02-04
  • 2018-08-15
相关资源
最近更新 更多