PostgreSQL:创建架构,无法授予特权

时间:2020-01-08 22:13:09

标签: postgresql

我正在创建一个新数据库(PostgreSQL v10)。如果我没有误会,我应该创建一个与之配套的架构,因为否则所有内容都属于公共架构,因此默认情况下所有用户都可以访问它。

不幸的是,当我尝试这样做时,我无法插入或选择数据,甚至无法删除我创建的表。

(最终,我希望有三个用户:一个可以添加和修改表,一个只能读取和写入数据(INSERT,SELECT,UPDATE,DELETE),另一个是只读(SELECT)。)

让我们将其简化为基本要素。我从没有数据库,没有模式,也没有用户开始。

postgres=# \dl
      Large objects
 ID | Owner | Description 
----+-------+-------------
(0 rows)

postgres=# \dn
  List of schemas
  Name  |  Owner   
--------+----------
 public | postgres
(1 row)

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# 

现在,我创建数据库,连接到数据库,并创建与数据库关联的架构,因为该数据库是当前数据库。我创建一个用户。 (我打算稍后创建更多用户,但让我们先开始工作。)

postgres=# CREATE DATABASE tn_beta_db;
CREATE DATABASE
postgres=# \c tn_beta_db
You are now connected to database "tn_beta_db" as user "postgres".
tn_beta_db=# CREATE SCHEMA tn_schema;
CREATE SCHEMA
tn_beta_db=# CREATE ROLE tn_beta_migrator
tn_beta_db-#     NOSUPERUSER NOCREATEDB NOCREATEROLE
tn_beta_db-#     NOINHERIT LOGIN NOREPLICATION
tn_beta_db-#     NOBYPASSRLS
tn_beta_db-#     PASSWORD 'secretword';
CREATE ROLE
tn_beta_db=# 

最后,我授予现有表(没有,但可能是一种很好的形式),未来表的特权,并在架构上创建权限。鉴于角色上的LOGIN似乎不必授予CONNECT特权,但它表达了意图。

tn_beta_db=# ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_migrator GRANT ALL ON TABLES TO tn_beta_migrator;
ALTER DEFAULT PRIVILEGES
tn_beta_db=# GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_migrator;
GRANT
tn_beta_db=# GRANT ALL ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_migrator;
GRANT
tn_beta_db=# GRANT CREATE ON SCHEMA tn_schema TO tn_beta_migrator;
GRANT
tn_beta_db=# 

最后,我以tn_beta_migrator的身份连接到数据库,并尝试执行某些操作。

[T] jeff@nantes-4:~ $ psql --username tn_beta_migrator --host localhost tn_beta_db
Password for user tn_beta_migrator: 
psql (10.10 (Ubuntu 10.10-0ubuntu0.18.04.1))
Type "help" for help.

tn_beta_db=> CREATE TABLE tn_schema.foo(x int);
CREATE TABLE
tn_beta_db=> INSERT INTO tn_schema.foo (x) VALUES (1);
ERROR:  permission denied for schema tn_schema
LINE 1: INSERT INTO tn_schema.foo (x) VALUES (1);
                    ^
tn_beta_db=> DROP TABLE tn_schema.foo;
ERROR:  permission denied for schema tn_schema
tn_beta_db=> 

在获得授权的情况下,我希望该数据库上的该用户能够插入刚刚创建的表中,然后删除该表。但这不能。

现在要更加清楚地了解世界现状:

tn_beta_db=# \l
                                     List of databases
    Name    |  Owner   | Encoding |   Collate   |    Ctype    |      Access privileges      
------------+----------+----------+-------------+-------------+-----------------------------
 postgres   | postgres | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 | 
 template0  | postgres | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 | =c/postgres                +
            |          |          |             |             | postgres=CTc/postgres
 template1  | postgres | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 | =c/postgres                +
            |          |          |             |             | postgres=CTc/postgres
 tn_beta_db | postgres | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 | =Tc/postgres               +
            |          |          |             |             | postgres=CTc/postgres      +
            |          |          |             |             | tn_beta_migrator=c/postgres
(4 rows)

tn_beta_db=# \dn
   List of schemas
   Name    |  Owner   
-----------+----------
 public    | postgres
 tn_schema | postgres
(2 rows)

tn_beta_db=# \du
                                       List of roles
    Role name     |                         Attributes                         | Member of 
------------------+------------------------------------------------------------+-----------
 postgres         | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 tn_beta_migrator | No inheritance                                             | {}

tn_beta_db=# 

关于我做错了或被误解的任何指示吗?

1 个答案:

答案 0 :(得分:2)

你错过了

GRANT USAGE ON SCHEMA tn_schema TO tn_beta_migrator;

我将坚持您的详细示例(在psql中以postgres用户身份连接到db postgres):

CREATE DATABASE tn_beta_db;
\c tn_beta_db
CREATE SCHEMA tn_schema;
CREATE ROLE tn_beta_migrator NOSUPERUSER NOCREATEDB NOCREATEROLE
NOINHERIT LOGIN NOREPLICATION ;
GRANT CREATE ON SCHEMA tn_schema TO tn_beta_migrator;
GRANT USAGE ON SCHEMA tn_schema TO tn_beta_migrator;
\c tn_beta_db tn_beta_migrator;
CREATE TABLE tn_schema.foo(x int);
INSERT INTO tn_schema.foo (x) VALUES (1);
SELECT * FROM tn_schema.foo;
DROP TABLE tn_schema.foo;
相关问题