Sql server 根据用户访问级别筛选数据的策略

Sql server 根据用户访问级别筛选数据的策略,sql-server,database-design,permissions,Sql Server,Database Design,Permissions,我们目前有一个非常简单的安全模式 我们有大致映射到表的资源,我们可以访问这些资源(添加、修改、删除、查询),我们还有组 每个权限由一个具有指定访问权限的资源和一个组组成 每个用户可以属于多个组 所以,权限是组、访问和资源之间的多对多关系 我们在用户和组之间也有一个多对多的关系 这正好满足我们的需要 我试图思考的是一种在记录级别使用类似方案授予数据权限的方法。我需要一种根据用户访问级别“过滤”记录的方法 例如,属于某个组的用户可以看到一个表(资源)的所有记录,但来自另一个组的用户只能看到满足特定条

我们目前有一个非常简单的安全模式

我们有大致映射到表的资源,我们可以访问这些资源(添加、修改、删除、查询),我们还有组

每个权限由一个具有指定访问权限的资源和一个组组成

每个用户可以属于多个组

所以,权限是组、访问和资源之间的多对多关系

我们在用户和组之间也有一个多对多的关系

这正好满足我们的需要

我试图思考的是一种在记录级别使用类似方案授予数据权限的方法。我需要一种根据用户访问级别“过滤”记录的方法

例如,属于某个组的用户可以看到一个表(资源)的所有记录,但来自另一个组的用户只能看到满足特定条件的记录,即他们可以看到过滤后的数据

我在考虑向权限表中添加一个“表达式”字段,以便在访问某个资源时应用过滤器(事实上,这会稍微复杂一些,我必须应用用户所属组的每个过滤器,并加上一个“或”)

我希望它尽可能通用和可配置


您将如何处理这样一个用例?

我知道您还没有答案-我当然不确定什么是适合您的正确答案,但以下是我对它的价值的看法

我可能误解了,但如果我试图对角色/组对资源实施细粒度的访问控制,我会在应用程序中执行,而不是在数据存储解决方案中

我不知道在这种情况下,这是否是您的选择,但如果您在数据层中实现这种安全性,您可能会遇到缺乏灵活性的问题,如果您最终使用专有扩展,甚至可能会出现供应商锁定问题


对这里的任何支持/冲突的观点都非常感兴趣。

您关于使用“表达式”进行筛选和动态创建SQL语句(对吗?)来筛选数据的想法应该是可行的。另一个真正的替代方案似乎需要一组固定的过滤器“轴”,用户可以在这些轴上定义对记录的访问。要在这两种基本机制之间做出选择,需要有关应用程序的更多细节。作为一个(明显的)例子,在我的雇主的应用程序中,每个客户(记录)都被分配到一个“办公室”,我们提供安全机制来控制哪些用户可以访问哪个办公室中的客户。这是使用我描述的第二种机制实现的,因为它对我们的应用程序设计至关重要。如果您正在构建更多的“元应用程序”,您可能希望实现更通用的解决方案,以便更容易地更改此行为。

我强烈建议您研究能够构造动态查询的ORM(对象关系映射)框架。基本思想是,您将根据登录用户的安全性在应用程序代码中构造标准,框架将其转换为SQL,并在服务器上执行(因此您不会将所有记录拉入应用层并在那里进行过滤)。这种方法与使用直接动态SQL的区别在于,ORM将允许您编写类型安全代码,而直接动态SQL是基于字符串的,这使得它容易出现人为错误

其中一些ORM框架提供了现成的授权功能,这可能(也可能不)与我上面描述的不同,但也可能完成任务

我确信llblgenpro有一个非常强大的动态查询引擎,并且支持行级授权。我不是NHibernate或实体框架方面的专家,但我确信他们也有这种支持


即使您不打算使用ORM进行持久化(它们的主要用途),也可能值得让它们看看它们的动态查询功能。

我们有一个如下所示的AccessControlEntry表:

CREATE TABLE [dbo].[AccessControlEntry]
(
    [subjectId] [nvarchar](256) NOT NULL,
    [objectType] [varchar](256) NOT NULL,
    [objectId] [int] NOT NULL,
    [permission] [varchar](50) NOT NULL,
    [flag] [int] NOT NULL DEFAULT (0),
    [applyToChildren] [int] NOT NULL DEFAULT (1),
    CONSTRAINT [PK_AccessControlEntry] PRIMARY KEY CLUSTERED ([subjectId] ASC, [objectType] ASC, [objectId] ASC, [permission] ASC)
)
我们正在为其设置权限的用户id是subjectId,objectType和objectId标识我们正在设置权限的对象(术语中的资源)。在我们的例子中,每个权限都有单独的记录(即列表、查看、创建、修改、删除),但您也可以轻松地为每个权限设置一列

然后,我们创建了一个表值函数,该函数接受subjectId、objectType和可选的objectId,并返回权限

一旦你有了它,你会在几乎所有的查询中看到这个表值函数,所以你可以过滤用户对资源的权限返回的内容


因为我们的数据本质上是分层的(有点像公司中的业务单元),所以我们的权限系统处理权限和继承的层次结构。我不熟悉您的数据模型,所以我不知道您对该模型也有要求,但这种想法类似于您对目录和文件应用安全权限的方式。

M$sql server。。。我们希望解读多对多关系,并为我们提供给定用户的资源和访问列表。。。我们所做的每一个查询都是动态的,这就是为什么我考虑添加一个表达式…这听起来确实很合乎逻辑,但我们有一个框架,其中大多数业务逻辑都是在数据库级别强制执行的,使用存储过程。。。我们的SP只接收xml,解析并相应地执行操作,我们的应用程序只需构建这些xml,并让DB验证所有内容……哇,你得到的有趣约束!祝你好运当用户数量适中(1000000)时,这似乎会使AccessControlEntry变得非常庞大。如果有十万个不同的对象,这意味着表中可能有10^11个条目。这是巨大的,,