【问题标题】:Postgres default privileges for readonly role只读角色的 Postgres 默认权限
【发布时间】:2020-04-07 14:47:29
【问题描述】:

我创建了一个 PostgreSQL(11.5 版)数据库,我想创建两种不同类型的主要角色(readonlyreadwrite),然后将这些角色分配给个人(user1user2 等.).

我一直在阅读 PostgreSQL 文档,并以这篇文章为例:https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/

但是,我无法正确设置权限。基本上,我希望角色readwrite 能够在此数据库中创建他们想要的任何架构和/或表,并且我希望角色readonly 能够从任何架构和/或表中创建SELECT在这个数据库中。但是,按照我下面的示例,user2 可以创建一个表,但 user1 无权访问该表。

我创建了以下脚本,我可以作为数据库的主用户运行它来创建数据库、架构和角色。

运行 SQL 脚本的命令:

psql -h <INSERT HOST HERE> -U postgres -W -f create_db.sql

create_db.sql 的内容

-- drop the existing database
DROP DATABASE IF EXISTS new_db;

-- create the database
CREATE DATABASE new_db;

-- connect to the database
\c new_db

-- create the new schema
CREATE SCHEMA new_schema;

-- revoke privileges from 'public' role
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE new_db FROM PUBLIC;

-- create readonly role
DROP ROLE IF EXISTS readonly;
CREATE ROLE readonly;
GRANT CONNECT ON DATABASE new_db TO readonly;
GRANT USAGE ON SCHEMA new_schema TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA new_schema TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT SELECT ON TABLES TO readonly;

-- create read/write role
DROP ROLE IF EXISTS readwrite;
CREATE ROLE readwrite;
GRANT CONNECT, CREATE ON DATABASE new_db TO readwrite;
GRANT USAGE, CREATE ON SCHEMA new_schema TO readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA new_schema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA new_schema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT USAGE ON SEQUENCES TO readwrite;

-- create users
DROP USER IF EXISTS user1;
DROP USER IF EXISTS user2;
CREATE USER user1 WITH PASSWORD 'password';
CREATE USER user2 WITH PASSWORD 'password';

-- grant privileges to users
GRANT readonly TO user1;
GRANT readwrite TO user2;

脚本运行成功后,我可以以user2的身份运行以下脚本,在新架构中创建表。

运行 SQL 脚本的命令

psql -h <INSERT HOST HERE> -d new_db -U user2 -W -f create_.sql

create_table.sql 的内容

-- drop the existing table
DROP TABLE IF EXISTS new_schema.new_table;

-- create a new table
CREATE TABLE new_schema.new_table (name VARCHAR, age INT);

-- insert data into the new table
INSERT INTO new_schema.new_table (name, age) VALUES ('Bob', 42);

现在,如果user1(只读)登录到数据库,我希望他们能够从这个新创建的表中SELECT,但是,他们似乎没有正确的访问权限。他们可以看到该表,但不能查询它。

psql -h <INSERT HOST HERE> -d new_db -U user1 -W
new_db=> \dt new_schema.*
           List of relations
   Schema   |   Name    | Type  | Owner 
------------+-----------+-------+-------
 new_schema | new_table | table | user2
(1 row)

new_db=> SELECT * FROM new_schema.new_table;
ERROR:  permission denied for table new_table

【问题讨论】:

    标签: database postgresql


    【解决方案1】:

    在 PostgreSQL 11.7 中,它适用于以下修改:

    1. 新创建的表必须由postgres用户
    2. 创建
    3. 或运行ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT SELECT ON TABLES TO readonly;必须由user2运行。

    例如,如果我以 user2 身份运行 create_table.sql 并进行上述修改:

    ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT SELECT ON TABLES TO readonly;
    ALTER DEFAULT PRIVILEGES
    
    CREATE TABLE new_schema.new_table (name VARCHAR, age INT);
    CREATE TABLE
    
    INSERT INTO new_schema.new_table (name, age) VALUES ('Bob', 42);
    INSERT 0 1
    
    $ psql -U user1 -d new_db
    psql (11.7)
    Type "help" for help.
    
    new_db=> select * from new_schema.new_table;
     name | age 
    ------+-----
     Bob  |  42
    (1 row)
    
    
    new_db=> \dp+ new_schema.new_table;
                                      Access privileges
       Schema   |   Name    | Type  |  Access privileges  | Column privileges | Policies 
    ------------+-----------+-------+---------------------+-------------------+----------
     new_schema | new_table | table | readonly=r/user2   +|                   | 
                |           |       | user2=arwdDxt/user2 |                   | 
    (1 row)
    

    我了解 ALTER DEFAULT PRIVILEGES 必须由未来涉及的对象的所有者运行。

    【讨论】:

    • 有趣的是ALTER DEFAULT PRIVILEGES必须由未来对象的所有者运行。我希望我可以作为主 postgres 用户运行它,然后将为现在和将来的所有角色和表设置它。
    猜你喜欢
    • 1970-01-01
    • 2014-02-26
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2021-10-18
    • 2020-09-14
    • 1970-01-01
    相关资源
    最近更新 更多