前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >『数据库权限设计』在Sqlserver关系数据库实现行列级别的权限设计

『数据库权限设计』在Sqlserver关系数据库实现行列级别的权限设计

作者头像
Excel催化剂
发布2024-06-17 17:57:42
690
发布2024-06-17 17:57:42
举报
文章被收录于专栏:Excel催化剂Excel催化剂

在BI的分析模型里,很常用的权限设置是行级别的权限控制,不同人可以查看不同的维度成员数据,如销售经理可以看到所有区域的数据,各业务人员,只能看到自己范围内的数据。

当然还有列权限的控制,如控制特定用户如财务用户可以访问某个字段如成本及其相关的衍生度量值,其他用户不可访问。

这些在PowerBI建模里,都不是难事。

但问题来了,不是所有的数据,都通过建模后分发的,关系型数据库能否也实现类似效果呢?

经过一番研究,在Sqlserver上是可以实现的,其他数据库暂时没精力研究,在Sqlserver2016及以后,可以实现这种行级别的权限控制。具体的实现代码如下:

代码语言:javascript
复制
-- 创建数据库和架构
CREATE DATABASE SalesDB;
GO

USE SalesDB;
GO

CREATE SCHEMA Security;
GO


-- 创建用户
CREATE USER Manager WITHOUT LOGIN;
CREATE USER Employee1 WITHOUT LOGIN;
CREATE USER Employee2 WITHOUT LOGIN;
CREATE USER Employee3 WITHOUT LOGIN;
GO


-- 创建目标表
CREATE TABLE dbo.Orders (
    OrderID INT PRIMARY KEY,
    SalesRep NVARCHAR(50),
    OrderAmount DECIMAL(18, 2)
);
GO

-- 插入示例数据
INSERT INTO dbo.Orders (OrderID, SalesRep, OrderAmount)
VALUES 
    (1, '1', 100.00),
    (2, '2', 200.00),
    (3, '3', 300.00),
    (4, '4', 400.00);
GO



-- 创建匹配表
CREATE TABLE Security.UserAccess (
    UserID NVARCHAR(50),
    CanViewUserID NVARCHAR(50)
);
GO

-- 插入示例数据
INSERT INTO Security.UserAccess (UserID, CanViewUserID)
VALUES 
    ('Manager', '1'),
    ('Manager', '2'),
    ('Manager', '3'),
    ('Employee1', '1'),
    ('Employee2', '2'),
    ('Employee3', '3');
GO


-- 创建行级别安全策略函数
CREATE FUNCTION Security.fn_securitypredicate(@SalesRep AS NVARCHAR(50))
RETURNS TABLE
WITH SCHEMABINDING
AS
    RETURN SELECT 1 AS fn_securitypredicate_result
    FROM Security.UserAccess
    WHERE CanViewUserID = @SalesRep
          AND UserID = USER_NAME();
GO



-- 删除已存在的安全策略
DROP SECURITY POLICY IF EXISTS SalesFilter;
GO

-- 创建新的安全策略并应用于目标表
CREATE SECURITY POLICY SalesFilter
ADD FILTER PREDICATE Security.fn_securitypredicate(SalesRep)
ON dbo.Orders
WITH (STATE = ON);
GO


-- 授予用户对 Orders 表的 SELECT 权限
GRANT SELECT ON dbo.Orders TO Manager;
GRANT SELECT ON dbo.Orders TO Employee1;
GRANT SELECT ON dbo.Orders TO Employee2;
GRANT SELECT ON dbo.Orders TO Employee3;
GO


-- 测试 Manager 用户
EXECUTE AS USER = 'Manager';
SELECT * FROM dbo.Orders;
REVERT;
GO


-- 测试 Employee1 用户
EXECUTE AS USER = 'Employee1';
SELECT * FROM dbo.Orders;
REVERT;
GO

-- 测试 Employee1 用户
EXECUTE AS USER = 'Employee2';
SELECT * FROM dbo.Orders;
REVERT;
GO

-- 测试 Employee1 用户
EXECUTE AS USER = 'Employee3';
SELECT * FROM dbo.Orders;
REVERT;
GO

上面的代码,使用EXECUTE AS USER模拟不同用户访问的效果。但如果用户层也使用这样一段代码,去模拟其他用户,岂不是白干了?

当然一般的用户,没有办法执行EXECUTE AS USER这个语句的,实在不放心,可以运行以下的代码排查下哪些用户有这个权限(sa这种管理员权限肯定有,在以下语句里返回空是正常的)。

代码语言:javascript
复制
SELECT pr.name AS principal_name, pr.type_desc AS principal_type, 
       pe.permission_name, pe.state_desc AS permission_state
FROM sys.database_permissions AS pe
JOIN sys.database_principals AS pr
    ON pe.grantee_principal_id = pr.principal_id
WHERE pe.permission_name = 'IMPERSONATE';

上面的是行级别的权限,列级别的权限,就没那么通用,就需要自己写个视图封装下,例如下面的代码,做一个匹配表,然后有权限的正常显示,没权限的返回NULL。

总结

有了在关系数据库里控制权限,可以更方便地分发数据,不局限于olap模型,特别是对于没条件使用olap建模技术,或者一些明细数据没必要建模后分享,用户需要享有更大的自主性时,这是一个不错的数据分享方案。

最后,有企业项目需求,随时找我

非常难得的全栈开发能力,从数据采集、生产、ETL处理清洗、建模、报表自动化等都能胜任,可以低成本、快速交付高质量项目。

专业人做专业事,没有一个工具简单到可以瞬间让普通人上手并产生巨大生产力。就如简单如Excel的OFFICE工具不同人使用都有很大的差距,更不用说RPA需要有编程思维群体才能深入掌握。

笔者15年数据及编程能力,尚且需要全时间学习一个月才稍微有感觉可以随心所欲根据需求做一些应用出来(效率还带不断练习提升)。目前已经是资深的RPA领域专家,能解决各种企业现实环境难题。

笔者能够带给你:花小成本,可以带来企业数据化流程自动化,带给企业立竿见影的降本增效。

借助笔者独特的多工具的熟练使用优势。借助低代码平台与工具,培训企业员工掌握并持续赋能业务,让业务部门减少IT团队依赖度,一样可以在办公自动化领域大有作为。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Excel催化剂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档