我已经在数据库级别的 Oracle 和 SQL Server 中完成了这项工作,也通过具有预设授权控制(非自由形式查询)的 Web 服务器,以及通过启用自由形式查询的 SQL 解析器完成了这项工作。我的看法:
1.方法一:使用数据库级机制,其中用户A为数据库用户
创建/拥有/完全控制所有表、视图和其他
对象,用户 B、C、D... 是使用的最终用户帐户
A 授予访问权限的对象。
一个。优点
一世。可能更容易维护;您可能需要更少的测试用例来确认它
正常工作
ii. 允许您分发使用直接 ODBC 连接的应用程序
(例如 Microsoft Access 文件)到多个用户,每个用户可以有单独的
行级安全
iii. 允许实时更新访问控制(个人权限,
或整个权限集),通过后端数据库更改
iv. 您不必担心应用程序的安全性,因为您依赖
所有安全性的数据库(包括您的管理员帐户的安全性)
湾。缺点:
一世。每个最终用户都需要一个单独的数据库用户帐户。这一般是
例如,对于成千上万的用户来说是不可取的
ii. 通过使用 ODBC,用户可以直接连接到数据库服务器,这可以
在某些情况下是安全漏洞(这取决于更多的因素,而不是
在这个问题的范围内)
iii. 性能受到重大打击。可扩展性的另一个障碍
iv. 由于这些和其他原因,这种方法通常不被认为是最好的
生产使用实践
C。执行:
一世。如您所述,对于 Oracle,有内置支持
ii. 对于 SQL Server,这可以使用视图和代替触发器来实现,
视图或存储过程执行 SELECT 和触发器执行写入的位置
以可控的方式。这样就可以完成任务了
但它很麻烦,并且需要相当多的代码,其中大部分需要
每当您的授权方法发生变化时(例如更改什么
哪些 ACL 表中的字段将根据
您要保护的表)。此外,每组代码都需要添加到每个
您要保护的表。另一方面,Oracle 做了类似的事情
解析 SQL 语句并在表时插入 where 子句
涉及到安全。这是一种更灵活的方法,但会非常
除非您可以在 T-SQL 中编写 SQL 解析器,否则很难在 SQL Server 中实现
iii. 对于 postgreql 和 mysql,我相信你可以实现与描述相同的方法
上面的 SQL Server,如果这是你想要的方式。我想,在 postgresql
您可以在 C 中编写一个 SQL 解析器,它执行转换以添加
必要的 where 子句,使其可用作数据库函数,传递您的自由
在触发器或存储过程中将此函数形成 SQL,并使用结果
修改后的 SQL 作为运行的查询(或者只是让 C 函数运行查询
并将其传递回视图)。但这对于一些添加的人来说可能是很多工作
您无法预料的查询的灵活性。
2.方法2:在中间使用应用程序。因此,您的应用程序要么使用用户 A 登录
并做它的事情(不推荐,但从技术上讲,工作正常),或者你可以设置一个
更受限制的用户 B 仅适用于您的应用程序,它可以执行任何最终用户的所有操作
可以做(例如查看/更改数据),但仅此而已(例如删除表)。你依靠
应用程序来控制访问。
一个。优点:这是大多数 Web 和类似的客户端-服务器应用程序的工作方式,您会发现
有很多资源可用于执行此操作
湾。缺点:
一世。如果您想为最终用户提供 ODBC 连接,则不能使用此方法
(或使用 ODBC 的应用程序)
ii. 正如您所指出的,通常这是以不允许的方式实现的
自由格式的 SQL。有两种方法可以解决后一个问题:
A. 创建您自己的 SQL 解析器(这是您的“代理”解决方案),您的应用程序
将用于解析任何自由格式的 SQL 请求(这最终将类似于
Oracle的实现,除了你的SQL猴子发生在你的应用程序中,
而 Oracles 出现在数据库中)。对于您的请求的所有元素
解析器标识为表,您将在 ACL 表中执行查找以确定
“WHERE”谓词与该表相关(如果有),将被添加到
SQL 请求在发送到服务器之前。如果您熟悉创建
您自己的编程语言解析器,这种方法应该不会太难,但如果不是,
您可能不想尝试——您可能会发现尝试解决即使是简单的用例
最终与解决任何用例一样复杂,因此您要么构建一个适当的
完全灵活的解析器,否则您将永远陷入错误修复的泥潭。在
此外,这种方法会像方法 1 一样严重影响您的表现。
B. 创建一个用户界面,提供您想要的查询功能类型,而无需
真正的自由形式。您必须确保接口可以支持每个
您想接受的可想象的查询。虽然根据您的要求这并不理想,
考虑到要完成的工作量,您可能会发现它是一种更具成本效益的方法
你的 SQL 解析器是正确的,如果你以前没有这样做过,
总的来说,如果您有一个非常小的项目,我的建议是使用方法 1,这样可以节省您使用 ODBC 的时间(例如,我在一个试点/测试项目中这样做了,我们在 Microsoft Access 中构建了应用程序2 周),否则,除非灵活性确实是第一优先级并且性能并不重要,否则使用方法 2 使用允许应用程序控制访问的结构化界面,并为您提供对性能的更大控制。