我们需要为客户提供对暂存数据库的访问权限,以便他们可以将数据提取到自己的服务器中,但每个表都包含所有客户数据。所有表都有一个“CustomerID”列。客户应该只看到 customerID 与他们相同的行。
我不是在寻找为每个客户创建单独的数据库或视图的建议,因为这两个建议都是高维护和低效率的。
我的解决方案必须与:
- 100GB 数据库
- 400张桌子
- 从核心事务数据库每 30 分钟更新一次
- 季度架构更改(应用程序处于持续开发中)。
谁能给我一个明确的答案,说明为什么以下方法不安全或不起作用?:
我为每个客户设置了一个数据库用户,他们的 customerID 作为扩展属性。
我创建了每个表的视图,该视图从表中动态选择 *,其中 customerID 列与登录用户的扩展属性 CustomerID 相同。代码如下所示,并且运行良好:
CREATE VIEW [CustomerAccessDatabase].[vw_Sales]
AS SELECT * FROM [CustomerAccessDatabase].[Sales]
WHERE [Sales].[CustomerID]=
(SELECT CONVERT(INT,p.value) AS [Value]
FROM sys.extended_properties
JOIN sys.sysusers ON extended_properties.major_id=sysusers.[uid]
AND extended_properties.name = 'CustomerID'
AND sysusers.[SID]=(SELECT suser_sid())
);
GO
为了提供对视图的访问,我创建了一个通用数据库角色“Customer_Access_Role”。此角色有权访问所有表视图,但拒绝访问数据库表本身。
为了防止用户更改自己的 customerID,我拒绝访问扩展属性,如下所示:
USE [master];
GO
DENY EXEC ON sys.sp_addextendedproperty to [public];
GO
DENY EXEC ON sys.sp_dropextendedproperty to [public];
GO
DENY EXEC ON sys.sp_updateextendedproperty to [public];
GO
最终结果是我只需要一个数据库和一组权限。
要添加新客户,我需要做的就是创建一个新用户,并将其 customerID 作为扩展属性,并将其添加到 Customer_Access_Role。而已!