如何为Postgresql中的所有数据库创建具有只读权限的用户?

问题描述:

我想为所有数据库中的所有表创建仅具有select特权的用户。我以为我可以得到数据库列表,并为每个数据库应用以下命令:如何为Postgresql中的所有数据库创建具有只读权限的用户?

GRANT select ON DATABASE dbname to user1; 

但我得到了以下错误:

ERROR: invalid privilege type SELECT for database 

当我一派人劝去做grant select操作所有表格。但新表总是被添加。所以这对我来说不是一个可接受的解决方案。有谁知道任何解决方法?

+0

@Jonas其实这是基本的SQL,所以不非常适合DBA - http://dba.stackexchange。com/faq – Stefano

你不能做到这一点在数据库级,只在架构层面。

假设你只使用public架构中的每个数据库,你可以这样做:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO user1; 
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO user; 
+2

您的声明表明这将适用于新创建的表和视图是不正确的 - “所有表”只是简单地用于在每个当前存在的表上运行GRANT SELECT,并且不设置任何默认值。要设置新对象的默认值,您需要ALTER DEFAULT PRIVILEGES命令:http://www.postgresql.org/docs/current/static/sql-alterdefaultprivileges.html(请参阅下面的答案) – IMSoP

+0

@IMSoP:感谢您指出说出来! –

+0

最初的问题是所有表和所有数据库的SELECt主题。这是可能的在MySQL中,但(我认为)不可能在postgres。在postgres中,必须为每个数据库单独授予这些权限。 也许你可以添加这个作为澄清(或纠正我,如果有可能的话)。 – Michael

我知道你已经说过,这不是一个可以接受的答案,但它是正确的答案呢。

指定安全(grant和revoke)是表设计和测试的一部分。

表定义,安全测试之前,不要移动表,生产和测试数据是版本控制之下。

话虽如此,PostgreSQL没有对数据库的任何SELECT权限。您只能授予数据库的CREATE,CONNECT或TEMP权限。

你可以在给定模式中的所有表授予SELECT。我不知道如何影响运行GRANT语句后创建的表,但它测试起来相当容易。

PostgreSQL Grant syntax

你需要做两件事情:第一,允许访问现有对象;其次,设置从现在开始创建的新对象的默认访问权限。请注意,授予对“TABLES”的访问权限包括视图,但不包括序列(例如“SERIAL”列的自动递增功能),因此您可能也希望授予对这些权限的访问权限。下面

的假定你想要做的public架构的一切。通过省略IN SCHEMA ...子句,ALTER DEFAULT PRIVILEGES语句可以作用于整个数据库;必须为每个模式运行一次GRANT

-- Grant access to current tables and views 
GRANT SELECT ON ALL TABLES IN SCHEMA public TO user1; 
-- Now make sure that's also available on new tables and views by default 
ALTER DEFAULT PRIVILEGES 
    IN SCHEMA public -- omit this line to make a default across all schemas 
    GRANT SELECT 
ON TABLES 
TO user1; 

-- Now do the same for sequences 
GRANT SELECT, USAGE ON ALL SEQUENCES IN SCHEMA public TO user1; 
ALTER DEFAULT PRIVILEGES 
    IN SCHEMA public -- omit this line to make a default across all schemas 
    GRANT SELECT, USAGE 
ON SEQUENCES 
TO user1; 

PostgreSQL的手动

+0

奇怪的是,我需要'授予使用架构公开给user1;'以及 –

Postgres的版本比9.0更低:

psql -d DBNAME -qAt -c "SELECT 'GRANT SELECT ON ' || tablename || ' TO USER;' 
FROM pg_tables WHERE schemaname = 'public'" | psql -d DBNAME 

psql -d DBNAME -qAt -c "SELECT 'GRANT SELECT ON ' || viewname || ' TO USER;' 
FROM pg_views WHERE schemaname = 'public'" | psql -d DBNAME 

psql -d DBNAME -qAt -c "SELECT 'GRANT SELECT ON ' || relname || ' TO USER;' 
FROM pg_statio_all_sequences WHERE schemaname = 'public'" | psql -d DBNAME 
+0

我必须做'psql -d DBNAME -qAt -c“SELECT'GRANT SELECT ON'|| relname ||'TO USER;' FROM pg_statio_all_tables WHERE schemaname ='public'“| psql -d DBNAME“ – tymik