我正在寻找一种良好的模式来实现适合在客户端 - >数据库环境中使用的行级安全控制(通过例如代理,中间人Web服务或存储过程)。我控制客户端和数据库。一些要求:
我曾经有过一些(非常好的)想法:
insert
,但我需要非常严格地锁定权限(例如,不创建函数)和there seem to be a lot of gotchas (like divide by zero) that leak information。我已经在这个主题上做了大量的谷歌搜索,但我还没有看到有人如何在真实场景中解决这个问题。有some documentation for MS SQL但似乎是discouraged in MySQL并且对于postgres基本上不存在写入。
这似乎是一个非常常见的问题,但我想很多人都在编写Web应用程序并且满足于将用户手铐放到某些经过预先审查的查询中,但我真的需要尽可能多地为用户提供查询与我的客户的数据。
答案 0 :(得分:2)
整个行级安全主题颇具争议。我个人对此的看法是,你正试图在数据库ACL层实现这一点。我知道Oracle支持这一点,但从一开始就是一个非常糟糕的主意,并且引起了更多的挫折而不是好。我知道你很想重复使用现有的访问控制功能只是为了节省代码行,但我自己也不敢走这条路只是因为你可能会因为ACL的预期与现实而陷入死胡同已实施与您希望如何运作。
答案 1 :(得分:1)
我已经在数据库级别的Oracle和SQL Server中以及通过具有预设授权控件(非自由格式查询)的Web服务器以及通过SQL解析器完成此操作表单查询。我的看法:
1. Approach 1: Use database-level mechanisms, where user A is the database user that creates / owns / fully controls all tables, views, and other objects, and user B, C, D... are the end user accounts that utilize the objects that A grants access to. a. Pros i. Might be easier to maintain; you may need fewer test cases to confirm that it works properly ii. Allows you to distribute an application that uses direct ODBC connections (such as a Microsoft Access file) to multiple users, who can each have separate row-level security iii. Allows real-time updates to access control (either to individual permissions, or to entire sets of permissions), via back-end database changes iv. You don't have to worry about application security, because you are relying on the database for all security (including the security of your admin account) b. Cons: i. Requires a separate database user account for each end user. This is generally not desirable for, for example, tens of thousands of users ii. By using ODBC, users are directly connecting to the database server, which could be a security weakness under some circumstances (which depends on more factors than are in scope for this question) iii. Performance takes a significant hit. Another barrier to scalability iv. For these and other reasons, this approach is generally not considered best practice for production use c. Implementation: i. For Oracle, as you noted, there is built-in support ii. For SQL Server, this can be implemented using views and instead-of triggers, where the view or stored proc does SELECTs and triggers perform writes in a controlled manner. This can get the job done, but it is cumbersome, and requires a fair amount of code, much of which needs to be changed whenever your authorization approach changes (such as changing what fields in what ACL tables will authorize what actions based on what values in the tables you want to secure). Furthermore, each set of code needs to be added to each table you want to secure. Oracle, on the other hand, does something akin to parsing the SQL statement and interjecting a where clause whenever the table you are securing is involved. This is a far more flexible approach, but would be very difficult to implement in SQL server unless you can write a SQL parser in T-SQL iii. For postgreql and mysql, I believe you can implement the same approach as described above for SQL Server, if this is the way you want to go. I suppose, in postgresql you could write a SQL parser in C which performs the transformation to add the necessary where clauses, make it available as a database function, pass your free- form SQL to this function in your trigger or stored proc, and use the resulting modified SQL as the query that gets run (or just have the C function run the query and pass that back to the view). But that might be a lot of work for some added flexibility for queries that you could not anticipate. 2. Approach 2: Use an application in the middle. So either your application uses User A to log in and do its stuff (not recommended, but technically, works fine), or you can set up a more restricted User B just for your application, which can do everything that any end user can do (e.g. view / change data), but nothing more (e.g. drop table). You rely on the application to control access. a. Pros: this is how most web and similar client-server applications work, and you'll find lots of resources available for doing this b. Cons: i. you can't use this approach if you want to provide end users with an ODBC connection (or an application that uses ODBC) ii. As you point out, usually this is implemented in a manner that does not allow for free-form SQL. There are two ways to address this latter concern: A. Create your own SQL parser (this is your "proxy" solution), which your application will use to parse any free-form SQL request (this will end up being similar to Oracle's implementation, except that your SQL monkeying occurs in your application, whereas Oracles occurs in the database). For all elements of the request that your parser identifies as a table, you will perform a lookup in your ACL table to determine what the "WHERE" predicate is (if any) related to that table, that will be added to the SQL request before it is sent to the server. If you are familiar with creating your own programming language parsers, this approach shouldn't be too hard, but if not, you might not want to try-- you may find that trying to solve even simple use cases ends up being just as complicated as solving any use case, so you either build a proper parser that is completely flexible, or you get mired in bug fixing forever. In addition, this approach will hit your performance hard just as Approach 1 does. B. Create a user-interface that provides the type of query functionality you want without truly being free-form. You would have to ensure the interface can support every conceivable query you want to accept. While this is not ideal based on what you asked, you may find it to be a more cost-effective approach given the amount of work to get your SQL parser correct, if you haven't done it before,
总的来说,如果您有一个非常小规模的项目,我的建议是采用方法1,它将节省您使用ODBC的时间(例如,我为我们构建应用程序的试验/测试项目做了这个微软Access在2周内),否则,除非灵活性确实是第一优先级且性能并不重要,否则使用方法2使用允许应用程序控制访问的结构化界面,并为您提供更好的控制权性能
答案 2 :(得分:0)
我在这里处理这样的代理https://github.com/jbaliuka/sql-analytic 它最初是为报告/分析目的而开发的,但我计划实现网关应用程序,以便我可以通过浏览器中的JavaScript导航数据库并使用DML执行SQL。它可能有用作Olingo插件,也可以将数据库作为OData服务发布。