7

我正在寻找一种很好的模式来实现适合在客户端-> 数据库环境中使用的行级安全控制(例如通过代理、中间人 Web 服务或存储过程)。我控制客户端和数据库。一些要求:

  • 禁止用户查看他们无权查看的查询结果中的行
  • 允许用户将自己的行插入和更新到表中,这使他们有权查看它们
  • (软要求)允许用户授予其他人读取或写入其行的权限
  • 在 Linux 上运行的开源或低成本解决方案。据我了解,没有免费的数据库可以实现行级安全性。甲骨文支持这一点,但它太$$$$。Postgres可能会在 9.4 中实现这一点,但它最初是针对 9.3 的并且滑倒了,并且有关于 ML 的讨论它可能会再次滑倒。我暂时考虑使用 postgres 只是因为它们似乎在此功能上走得最远。

我有一些(不是非常好的)想法:

  • 使用 postgresql 的安全屏障视图并拒绝用户访问基础表。不幸的是,没有将行插入安全屏障视图的好方法,因此某些特权代理/Web 服务将不得不处理插入语句。这似乎很难做对。
  • 使用常规视图,并拒绝用户访问基础表。这允许insert,但我需要非常严格地锁定权限(例如,不创建函数),并且似乎有很多泄漏信息的陷阱(如除以零)
  • 定义 SQL 的某个子集,并创建一个代理,它是您与数据库的唯一通信点。代理解析您的 SQL 查询并重写它以强制执行安全要求。一般来说,这似乎很难做到,但也许在 postgres 真正实现行级安全性之前,我可以使用一个非常小的 SQL 子集。
  • 只是为不同的用户(甚至不同的数据库)提供不同的表。但是,我不确定这适用于很多用户的效果如何。此外,这似乎不符合软要求。
  • 找到一些实际支持这一点的商业但成本合理的数据库
  • 使用Veil但是好像没有维护,并且有其他解决方案的大部分限制

我在这个话题上做了很多谷歌搜索,但我还没有看到有人在现实世界的场景中如何解决这个问题的事后分析。有一些 MS SQL 的文档,但在 MySQL 中似乎不鼓励使用,并且 postgres 基本上不存在文章。

这似乎是一个非常普遍的问题,但我想很多人正在编写 Web 应用程序并且满足于将他们的用户束缚在某些预先审查过的查询中,但我真的需要给我的用户尽可能多的灵活性来查询数据我的客户。

4

3 回答 3

2

整个行级安全话题颇具争议。我个人对此的看法是,您在试图在数据库 ACL 层实现这一点时对错误的树大喊大叫。我知道甲骨文支持这一点,但在我看来,从一开始这就是一个非常糟糕的主意,并且造成的挫败感多于好处。我知道您很想重用现有的访问控制功能只是为了节省代码行,但我自己不敢走这条路,因为您可能会因为 ACL 如何的期望与现实而陷入死胡同实施与您希望它如何工作。

于 2014-04-11T22:15:18.013 回答
1

我已经在数据库级别的 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 使用允许应用程序控制访问的结构化界面,并为您提供对性能的更大控制。

于 2014-09-03T03:22:29.723 回答
0

我正在处理这样的代理https://github.com/jbaliuka/sql-analytic 它最初是为报告/分析目的而开发的,但我计划实现网关应用程序,以便我可以通过 JavaScript 导航 DB 并使用 DML 执行 SQL浏览器。它也可以作为 Olingo 插件将数据库发布为 OData 服务。

于 2016-04-12T13:17:24.523 回答