如何判断SQL Server的Row Level Security安全策略是否过滤了查询返回的行
SQL Server行级安全策略生效状态查询方案
方案1:测试环境可用(对比RLS开关前后的行数)
适合非生产环境快速验证,操作逻辑如下:
- 先开启RLS策略执行目标查询,记录返回行数
- 临时关闭RLS策略后执行相同查询,记录完整行数
- 对比两个行数即可判断是否有数据被过滤
示例代码:
-- 1. 记录RLS生效时的查询结果行数 DECLARE @filtered_count INT; SELECT @filtered_count = COUNT(1) FROM wage WHERE wage > 200; -- 替换为你的实际查询条件 -- 2. 临时关闭RLS策略,记录完整结果行数 ALTER SECURITY POLICY <替换为你的RLS策略名称> WITH (STATE = OFF); GO DECLARE @full_count INT; SELECT @full_count = COUNT(1) FROM wage WHERE wage > 200; -- 和上面的查询条件保持一致 GO -- 恢复RLS策略启用状态 ALTER SECURITY POLICY <替换为你的RLS策略名称> WITH (STATE = ON); GO -- 输出判断结果 SELECT CASE WHEN @filtered_count < @full_count THEN '是,过滤器已生效' ELSE '否,过滤器对当前查询无影响' END AS 策略生效状态;
方案2:生产环境可用(无需修改RLS配置)
不用改动现有安全策略,直接基于RLS的过滤规则判断目标查询范围内是否存在需要被过滤的行即可,逻辑和你的示例场景完全匹配:
如果目标查询的条件范围内,存在符合RLS过滤规则的行,说明策略会生效,否则无影响。
示例代码:
DECLARE @exist_filtered_row BIT; SELECT @exist_filtered_row = CASE WHEN EXISTS( SELECT 1 FROM wage w INNER JOIN [User] u ON w.userid = u.id -- 下方替换为你的实际查询WHERE条件 WHERE w.wage > 200 -- 下方替换为你的RLS策略中需要过滤的用户规则 AND u.status = 'vip' ) THEN 1 ELSE 0 END; SELECT CASE WHEN @exist_filtered_row = 1 THEN '是,过滤器已生效' ELSE '否,过滤器对当前查询无影响' END AS 策略生效状态;
验证示例匹配性
- 当查询条件为
wage > 200时,存在vip用户mark的工资500符合条件,返回「是,过滤器已生效」 - 当查询条件为
wage < 200时,没有vip用户的工资符合该条件,返回「否,过滤器对当前查询无影响」
方案3:执行计划验证
不需要执行完整查询,查看目标查询的实际执行计划即可判断:
- 如果执行计划中存在RLS对应的过滤逻辑节点(即关联用户表判断权限的逻辑),且该节点的输出行数少于输入行数,说明RLS已过滤数据,策略生效。
内容的提问来源于stack exchange,提问作者Commodus
相关产品推荐
相关产品推荐

