我绝不是一名 DBA。我的目标是让一个用户(用户名)访问单个模式(user_schema)表和视图,而不需要 PostgreSQL 15.3 上的其他模式[psql(15.3(Debian 15.3-0+deb12u1),服务器 15.4)]。
我所做的是:
CREATE ROLE username LOGIN PASSWORD 'user_passwd';
CREATE SCHEMA user_schema;
ALTER USER username SET search_path = user_schema; -- Set the search path to 'user's schema'
GRANT USAGE ON SCHEMA olga TO username;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA user_schema TO username;
REVOKE SELECT ON ALL TABLES IN SCHEMA other_schema FROM username;
所以当我通过以下方式连接到数据库时:
$ psql -h <PUBLIC_IP> -U username -d postgres
Password for user username:
psql (15.3 (Debian 15.3-0+deb12u1), server 15.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
postgres=> show search_path;
search_path
-------------
user_schema
(1 row)
postgres=>
我确认我已经定向到正确的架构并且可以访问其中的所有内容!
但是,输入 other_schema。和选项卡,我得到了一些选项卡补全效果:
postgres=> SELECT * FROM other_schema.;
Display all 190 possibilities? (y or n)
这是不受欢迎的。
虽然我在针对特定表时得到了正确的行为
postgres=> SELECT * FROM other_schema.table_name;
ERROR: permission denied for schema other_schema
LINE 1: SELECT * FROM other_schema.table_name;
^
postgres=>
如何避免这种行为,从而完全隔离 username 对 user_schema 对象的访问?
这是与自动完成相关的情况吗?如果是的话我该如何处理?
此外,我希望这种隔离能够传播到所有元和反斜杠命令(\dt、\l、\dn ...等)。
现在我可以从任何地方看到一切:
postgres=> \dn
List of schemas
Name | Owner
--------------+---------------------
other_schema | postgres
public | pg_database_owner
user_schema | postgres
(3 rows)
将 search_path 设置为 user_schema 时,我希望结果是:
postgres=> \dn
List of schemas
Name | Owner
--------------+---------------------
user_schema | postgres
(1 rows)
很像
\l
...
postgres=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
---------------+-------------------+----------+------------+------------+------------+-----------------+-----------------------------------------
postgres | cloudsqlsuperuser | UTF8 | en_US.UTF8 | en_US.UTF8 | | libc |
| | | | | | | cloudsqlsuperuser=CTc/cloudsqlsuperuser
(1 rows)
postgres=>
您应该先撤销所有权限,然后再授予特定权限。例如:
CREATE ROLE username LOGIN PASSWORD 'user_passwd';
CREATE SCHEMA user_schema;
ALTER USER username SET search_path = user_schema;
REVOKE ALL ON DATABASE db_1 from public;
REVOKE ALL ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC;
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM PUBLIC;
REVOKE ALL PRIVILEGES ON SCHEMA information_schema FROM PUBLIC;
GRANT CONNECT, TEMPORARY ON DATABASE db_1 TO username;
GRANT USAGE, CREATE ON SCHEMA user_schema TO username;
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA user_schema TO username;
GRANT USAGE, SELECT, UPDATE ON ALL SEQUENCES IN SCHEMA user_schema TO username;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA user_schema TO username;