SQL Server行级安全(RLS)实现:管理员与普通用户权限控制
行级安全(RLS)谓词函数实现方案(针对fin.RLS_Data表)
核心实现思路
通过OR逻辑拆分管理员与普通用户的访问规则,管理员(硬编码账号或标记isAdmin的用户)直接获得全表访问权限,普通用户仅能访问匹配DataProviderId的数据,彻底解决内连接导致的管理员权限受限问题。
谓词函数代码
CREATE OR ALTER FUNCTION fin.fn_RLS_RLS_Data_Access(@DataProviderId INT) RETURNS TABLE WITH SCHEMABINDING AS RETURN SELECT 1 AS IsAccessible WHERE -- 管理员全量访问条件:硬编码账号或stg.UserAccess中标记为isAdmin的用户 ( SUSER_SNAME() IN ('dbo', 'DBENTPBIPROD') OR EXISTS ( SELECT 1 FROM stg.UserAccess ua WHERE ua.UserName = SUSER_SNAME() AND ua.isAdmin = 1 ) ) -- 普通用户仅能访问匹配的DataProviderId OR EXISTS ( SELECT 1 FROM stg.UserAccess ua WHERE ua.UserName = SUSER_SNAME() AND ua.DataProviderId = @DataProviderId );
安全策略创建
CREATE OR ALTER SECURITY POLICY fin.RLS_RLS_Data_Policy ADD FILTER PREDICATE fin.fn_RLS_RLS_Data_Access(DataProviderId) ON fin.RLS_Data WITH (STATE = ON);
关键说明
- 用
OR逻辑分离规则:管理员条件优先匹配,满足时直接返回可访问,无需校验DataProviderId,确保全表权限。 - 采用
EXISTS子查询替代内连接:避免因用户不在stg.UserAccess表(如硬编码管理员)而被过滤。 SCHEMABINDING约束:绑定函数与底层表结构,防止表结构变更导致RLS规则失效。- 动态获取当前用户:通过
SUSER_SNAME()获取登录账号,适配不同用户的权限校验。
内容的提问来源于stack exchange,提问作者rp346
相关产品推荐
相关产品推荐

