我第一次尝试创建 Postgres 数据库。
我为必须从我的 PHP 脚本访问数据库的 DB 角色分配了基本的只读权限,我有一个好奇心:如果我执行
GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;
有没有必要也执行这个?
GRANT USAGE ON SCHEMA schema TO role;
来自文档:
USAGE:对于模式,允许访问包含在模式中的对象 指定的模式(假设对象自己的特权 也满足要求)。这基本上允许受让人 “查找”模式中的对象。
我认为如果我可以选择或操作模式中包含的任何数据,我就可以访问模式本身的任何对象。我错了吗?如果不是,
GRANT USAGE ON SCHEMA
是做什么用的?文档中“假设对象自身的特权要求也得到满足”的确切含义是什么?
GRANT
是分开的。 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-------
)然后没有人else 可以列出目录以查看文件是否存在。
如果您要授予文件的世界读取权限(模式
rw-r--r--
)但不更改目录权限,则没有任何区别。没有人可以see文件来阅读它,因为他们无权列出目录。
如果您改为在目录上设置
rwx-r-xr-x
,将其设置为人们可以列出和遍历目录但不更改文件权限,人们可以 list 文件但不能 read 因为他们没有访问权限到文件。
您需要为人们设置both权限才能真正查看文件。
Pg 中的相同内容。您需要架构
USAGE
权限和对象权限才能对对象执行操作,例如表中的 SELECT
。
(类比有点下降,因为 PostgreSQL 还没有行级安全性,因此用户仍然可以通过直接从
SELECT
pg_class
来“看到”该表存在于模式中。他们不能'不过,我们没有以任何方式与之交互,所以只是“列表”部分不太一样。)
对于生产系统,你可以使用这个配置:
--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
只有在分配了用户后,我才设法对数据库进行操作
GRANT ALL PRIVILEGES ON DATABASE chat_db to chat_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA security_user TO chat_user;
GRANT USAGE ON SCHEMA security_user TO chat_user;
GRANT ALL PRIVILEGES ON TABLE web_history_migration TO chat_user;
ALTER SCHEMA security_user OWNER TO chat_user;
因为我在那里使用了 flywaydb。
虽然也许就足够了:
ALTER SCHEMA security_user OWNER TO chat_user;