我想将一个相当简单的、内部的、数据库驱动的应用程序从 SQLite3 迁移到 PostgreSQL 9.3,并在执行过程中收紧数据库中的权限。
该应用程序当前包含一个用于更新数据的命令;和一个查询它。当然,我还需要以其他方式维护数据库(创建新表、视图、触发器等)。
虽然此应用程序一开始将是唯一托管在服务器上的应用程序,但我更愿意假设它将来可能会托管在具有其他数据库的服务器上,而不是在以后有必要时进行争夺未来。
我认为这些将是一组相当常见的要求,但我很难找到一个简单的教程来解释如何在 PostgreSQL 中设置一个新数据库,并使用这种用户/权限分离。参考资料详细介绍了组、用户、角色、数据库、模式和域;但我觉得他们很困惑。
这是我到目前为止尝试过的(从内部psql作为“postgres”):
CREATE DATABASE hostdb;
REVOKE ALL ON DATABASE hostdb FROM public;
\connect hostdb
CREATE SCHEMA hostdb;
CREATE USER hostdb_admin WITH PASSWORD 'youwish';
CREATE USER hostdb_mgr WITH PASSWORD 'youwish2';
CREATE USER hostdb_usr WITH PASSWORD 'youwish3';
GRANT ALL PRIVILEGES ON DATABASE hostdb TO hostdb_admin;
GRANT CONNECT ON DATABASE hostdb TO hostdb_mgr, hostdb_usr;
ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO hostdb_mgr;
ALTER DEFAULT PRIVILEGES …Run Code Online (Sandbox Code Playgroud) ALTER DEFAULT PRIVILEGES
FOR ROLE engineering
IN SCHEMA reference
GRANT SELECT ON TABLES to analytics;
Run Code Online (Sandbox Code Playgroud)
该语法运行并具有有效含义。它的实现方式是,每当engineering 角色创建一个表(在reference模式中)时,该角色的任何成员都reporting将自动拥有对该表的读取访问权限。但要使其发挥作用,您必须在创建表时以角色身份登录或模拟(set session authorization等set role) 。engineering
我理解postgres 实现这一点的方式背后的基本原理。他们希望每个角色/用户设置自己的默认值。默认值是一种方便的简写,因此用户不必为他们创建的每个表设置权限。Postgres 甚至允许某人为他们可以模拟的任何角色设置默认值(因此超级用户可以为每个人设置默认值)。这非常强大,但是 postgres 不想让它变得太强大。他们仍然希望人们必须为每个用户的默认值发出单独的命令。他们希望人们认真思考他们为他们提供这种便利的每一位用户。
但是,我已经认真考虑过,我确实想为整个团队提供这些便利。我想要一个命令,让工程团队中的每个用户都继承这些默认权限。然后,每次他们中的一个创建一个表时,每个报告成员都会自动读取该表。事实上,当我第一次发现可以包含该子句时,这就是我解释语法的方式FOR ROLE engineering。但默认值不会被继承。
或者,我也对一个解决方案感兴趣,无论谁(无论他们位于哪个团队)在模式中创建一个表reference,该角色的所有成员都可以读取该表reporting。reporting因此,在这种变体中,即使我无法(直接)控制谁授予这些权限(以及为什么我想要这样做?),我仍然可以打开架构。如果我有这个解决方案,我仍然可以有效地将其限制为engineering团队成员(如果他们是架构中唯一具有创建权限的人)reference。
我是否遗漏了某些内容(例如替代语法)?或者还有其他解决方法吗?
我对任何解决方案(甚至构建自定义扩展)持开放态度,只要它不属于以下两个类别之一:
即每次团队成员engineering登录或创建表时,他们都必须执行一些额外的命令来处理权限(例如在启动会话时更改工程角色)
我按照以下步骤操作。
postgres通过 ( sudo -i -u postgres)登录的new_user通过 shell 脚本创建了新用户createuser --interactivecreatedb new_db.现在我想授予new_user权限,能够对他自己创建的表执行所有默认的 DML 操作(下面的命令取自这个问题),所以我输入:
postgres=# ALTER DEFAULT PRIVILEGES FOR new_user IN SCHEMA
public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO new_user;
Run Code Online (Sandbox Code Playgroud)
但是得到了一个错误:
ERROR: syntax error at or near "new_user"
LINE 1: ALTER DEFAULT PRIVILEGES FOR new_user IN SCHEMA public GRANT...
Run Code Online (Sandbox Code Playgroud)
我不知道为什么这个命令不起作用。