在模式上使用 GRANT 具体做什么?

我第一次尝试创建 Postgres 数据库。

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

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

还需要执行这个吗?

GRANT USAGE ON SCHEMA schema TO role;

来自 文件:

用法: 对于模式,允许访问 指定的模式(假设对象自己的特权 基本上,这可让受让人 “查找”模式中的对象。

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

207405 次浏览

不同对象上的 GRANT是独立的。数据库上的 GRANTing 没有 GRANT对其中模式的权限。类似地,模式上的 GRANTing 不授予内部表的权限。

如果您有从表中访问 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模式具有对角色 public的所有权限的默认 GRANT,每个用户/组都是 public的成员。所以每个人都已经在那个模式上有了用法。

这句话:

(假设对象自己的特权需求也得到满足)

也就是说,您必须在模式上使用 USAGE才能在其中使用对象,但是在模式上使用 USAGE本身并不足以在模式中使用对象,您还必须对对象本身拥有权限。

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

如果授予文件的全局读取权限(模式为 rw-r--r--) ,但不更改目录权限,则不会产生任何差异。没有人可以 文件为了读取它,因为他们没有权利列出目录。

如果你在目录上设置了 rwx-r-xr-x,这样人们可以列出并遍历目录,但是不能改变文件权限,人们可以 名单文件,但是不能 文件,因为他们没有访问文件的权限。

您需要设置 都有权限,以便人们能够实际查看文件。

Pg 也是一样。您需要模式 USAGE权限和对象权限来对对象执行操作,比如从表中执行 SELECT

(这个类比有点失败,因为 PostgreSQL 还没有行级安全性,所以用户仍然可以通过 pg_class中的 SELECTing 直接“看到”模式中存在表。不过,它们不能以任何方式与其交互,所以只是“列表”部分不太一样。)

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

--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 ;

好了,这是我对 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