173

我第一次尝试创建 Postgres 数据库。所以这可能是一个愚蠢的问题。

我为必须从我的 PHP 脚本访问数据库的 DB 角色分配了基本只读权限,我有一个好奇心:如果我执行

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

是否还需要执行此操作?

GRANT USAGE ON SCHEMA schema TO role;

文档中:

用法:对于模式,允许访问包含在指定模式中的对象(假设也满足对象自身的权限要求)。本质上,这允许被授权者在模式中“查找”对象。

我认为如果我可以选择或操作模式中包含的任何数据,我就可以访问模式本身的任何对象。我错了吗?如果不是,那是GRANT USAGE ON SCHEMA用来做什么的?文档中的“假设也满足对象自身的特权要求”究竟意味着什么?

4

3 回答 3

179

GRANT不同对象上的 s 是分开的。GRANT对数据库进行操作对其中的架构没有GRANT权限。类似地,GRANT对模式进行 ing 不会授予对其中表的权限。

如果您有权访问SELECT表,但无权在包含它的架构中查看它,则您无法访问该表。

权限测试按顺序进行:

Do you have `USAGE` on the schema? 
    No:  Reject access. 
    Yes: Do you also have the appropriate rights on the table? 
        No:  Reject access. 
        Yes: Check column privileges.

您可能会感到困惑,因为public架构默认GRANT具有角色的所有权限public,每个用户/组都是该角色的成员。因此,每个人都已经在该架构上使用过。

词组:

(假设也满足对象自身的权限要求)

是说您必须拥有USAGE架构才能使用其中的对象,但是拥有USAGE架构本身并不足以使用架构中的对象,您还必须拥有对象本身的权限。

它就像一个目录树。如果您创建一个somedir包含文件的目录,somefile然后将其设置为只有您自己的用户可以访问该目录或文件(rwx------目录上的模式rw-------,文件上的模式),那么没有其他人可以列出该目录以查看该文件是否存在。

如果您要授予对文件 (mode rw-r--r--) 的全局读取权限,但不更改目录权限,则没有任何区别。没有人可以看到该文件以阅读它,因为他们没有列出目录的权限。

如果您改为设置rwx-r-xr-x目录,将其设置为人们可以列出和遍历目录但不更改文件权限,人们可以列出文件但无法读取它,因为他们无权访问该文件。

您需要为人们设置这两种权限才能实际查看文件。

Pg中的相同内容。您需要架构USAGE权限和对象权限才能对对象执行操作,例如SELECT从表中执行操作。

(这个类比有点落空,因为 PostgreSQL 还没有行级安全性,所以用户仍然可以通过SELECTing frompg_class直接“看到”表存在于模式中。他们不能以任何方式与之交互, 但是,所以它只是“列表”部分并不完全相同。)

于 2013-06-27T23:45:48.870 回答
93

对于生产系统,您可以使用以下配置:

--ACCESS DB
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT  CONNECT ON DATABASE nova  TO user;

--ACCESS SCHEMA
REVOKE ALL     ON SCHEMA public FROM PUBLIC;
GRANT  USAGE   ON SCHEMA public  TO user;

--ACCESS TABLES
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
GRANT SELECT                         ON ALL TABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write ;
GRANT ALL                            ON ALL TABLES IN SCHEMA public TO admin ;
于 2015-03-04T08:24:54.230 回答
8

好吧,这是我针对 Linux 的简单数据库的最终解决方案:

# Read this before!
#
# * roles in postgres are users, and can be used also as group of users
# * $ROLE_LOCAL will be the user that access the db for maintenance and
#   administration. $ROLE_REMOTE will be the user that access the db from the webapp
# * you have to change '$ROLE_LOCAL', '$ROLE_REMOTE' and '$DB'
#   strings with your desired names
# * it's preferable that $ROLE_LOCAL == $DB

#-------------------------------------------------------------------------------

//----------- SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - START ----------//

cd /etc/postgresql/$VERSION/main
sudo cp pg_hba.conf pg_hba.conf_bak
sudo -e pg_hba.conf

# change all `md5` with `scram-sha-256`
# save and exit

//------------ SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - END -----------//

sudo -u postgres psql

# in psql:
create role $ROLE_LOCAL login createdb;
\password $ROLE_LOCAL
create role $ROLE_REMOTE login;
\password $ROLE_REMOTE

create database $DB owner $ROLE_LOCAL encoding "utf8";
\connect $DB $ROLE_LOCAL

# Create all tables and objects, and after that:

\connect $DB postgres

revoke connect on database $DB from public;
revoke all on schema public from public;
revoke all on all tables in schema public from public;

grant connect on database $DB to $ROLE_LOCAL;
grant all on schema public to $ROLE_LOCAL;
grant all on all tables in schema public to $ROLE_LOCAL;
grant all on all sequences in schema public to $ROLE_LOCAL;
grant all on all functions in schema public to $ROLE_LOCAL;

grant connect on database $DB to $ROLE_REMOTE;
grant usage on schema public to $ROLE_REMOTE;
grant select, insert, update, delete on all tables in schema public to $ROLE_REMOTE;
grant usage, select on all sequences in schema public to $ROLE_REMOTE;
grant execute on all functions in schema public to $ROLE_REMOTE;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on tables to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on sequences to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on functions to $ROLE_LOCAL;

alter default privileges for role $ROLE_REMOTE in schema public
    grant select, insert, update, delete on tables to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant usage, select on sequences to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant execute on functions to $ROLE_REMOTE;

# CTRL+D
于 2019-07-22T14:26:41.343 回答