我正在开发一个带有PostgreSQL数据库后端的文件管理系统。我正在使用将连接和查询数据库服务器的Qt库编写客户端。
默认情况下,文件管理系统将访问顶级目录限制为所有用户,除非特定用户有权访问特定的顶级目录。只要提供访问权限的用户已经访问他/她自己,任何人都可以访问任何人。这是通过使用2个外键维护数据库中的表来完成的:userID_fk和directoryID_fk。如果此表中存在记录,并且特定用户可以访问特定目录,则该目录将显示在用户的屏幕上。否则,该目录对用户不可见。
这种设计提出了一个挑战:用户已经能够连接到数据库,并且就数据库服务器而言是合法用户,因此对于无权访问的用户来说这很容易。一些目录通过简单地连接到不使用我的客户端应用程序的数据库服务器来给自己访问,并且只是在表中添加具有目录id和他们自己的用户id的记录。但是,我不能允许这样做。
我想要实现的是为所有数据库用户提供对数据库服务器的完全访问权限,但只能通过我自己的客户端应用程序而不是在其外部。
我想到了解决这一挑战的几种方法,但我正在寻求关于阻止用户访问客户端应用程序之外的数据库服务器的最佳架构的建议。
我想到的可能的设计方法:
然而,这种设计对用户来说很麻烦 - 用户必须提供密码才能连接到我的服务器"然后是第二个连接数据库服务器的密码。在我的特定情况下,数据库服务器上的数据也是加密的,这意味着用户必须提供第三个密码才能访问数据库。对于我认为的普通用户来说,这有点多了。
除了这两种方法之外,我还没有想到更好的设计。我非常感谢您的建议,包括您对我提出的设计的看法。非常感谢。
答案 0 :(得分:1)
我们在MS SQL Server下遇到了一个非常类似的问题,并通过在存储过程级别提供“API”来解决它。希望你能在PostgreSQL下做类似的事情。
这个想法是禁止所有客户端直接查询数据库。相反,您只对“公共”存储过程授予“执行”权限。 “私有”程序(即实施细节)和表格完全无法访问到外部客户端。
公共和私有过程共同实现了行级安全性和所需的任何其他业务逻辑。由于所有客户端都通过此API“漏斗”,因此没有人可以规避行级安全性或任何业务规则。这包括可以实现与现有数据库“对话”的任何未来应用程序。
在我们的案例中,我们在数据库用户和我们的“应用程序用户”之间进行了1:1的映射,并且只需让DBMS在登录期间对用户进行身份验证(这也有与Active Directory集成的额外好处,这很重要在我们的情况下)。然后,存储过程将使用当前数据库用户名来实现行级安全性。
您还应该考虑安全性缓存。在我们的例子中,我们有一个非常复杂的安全机制,支持权限继承(从父对象到子对象)和工作流,这使得计算成本很高 - 因此我们实现了一个“懒惰”更新的安全缓存,并防止重复的安全计算。安全缓存完全隐藏在存储过程后面,对客户端透明。根据您的安全机制的复杂性,您可能会考虑某种安全缓存在性能方面是否是一个好主意......
答案 1 :(得分:0)
我认为你最好使用Postgres的内置安全系统,而不是自己编写。
每个用户都有自己的用户名/密码(或者您可以使用SSL证书或Kerberos)
Postgres支持用户和角色,以及对表,模式等的访问控制以及列安全性。
目前,您需要使用表中的“所有者”列模拟行安全性,以及阻止用户查看不应该看到的行的视图。您需要找出“共享”,可能需要使用ACL数组列(允许的角色)或使用相关表。
9.3具有security_barrier视图,可防止某些窥探。在9.4中,它们是可更新的。 9.4还支持WITH CHECK OPTION视图,这在这里很有用。 9.4应该在本周晚些时候出来。
同样请参阅http://veil.projects.pgfoundry.org/curdocs/main.html。
基本示例:
create schema data;
create table data.files (
file_id int primary key,
name text not null,
owner name not null default current_user, --use a trigger in real world
acl name[] null
);
create view files as
select
*
from data.files
where
owner = current_user
or acl && array[current_user]; --&& is array overlap operator
insert into data.files values (1, 'test', 'admin', '{CSLover}');
你显然需要添加其他东西。