你如何在PostgreSQL中创build只读用户?

我想在PostgreSQL中创build一个只能从一个特定的数据库执行SELECT操作的用户。 在MySQL中,命令是:

GRANT SELECT ON mydb.* TO 'xxx'@'%' IDENTIFIED BY 'yyy'; 

什么是PostgreSQL中的等价命令或一系列命令?

我试过了…

 postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy'; postgres=# GRANT SELECT ON DATABASE mydb TO xxx; 

但是看起来,您可以授予数据库的唯一东西是CREATE,CONNECT,TEMPORARY和TEMP。

将使用/select授予一个表

如果您只授予连接到数据库,用户可以连接,但没有其他权限。 你必须像这样分别在表和视图上的名字空间(模式)和SELECT上授予USAGE:

 GRANT CONNECT ON DATABASE mydb TO xxx; -- This assumes you're actually connected to mydb.. GRANT USAGE ON SCHEMA public TO xxx; GRANT SELECT ON mytable TO xxx; 

多个表/视图(PostgreSQL 9.0+)

在PostgreSQL的最新版本中,您可以使用单个命令授予架构中所有表/视图/ etc的权限,而不必逐个input它们:

 GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx; 

这只会影响已经创build的表。 更有力的是,您可以在将来自动将默认angular色分配给新对象 :

 ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO xxx; 

请注意,默认情况下,这只会影响发出此命令的用户创build的对象(表):尽pipe它也可以在颁发用户所属的任何angular色上设置。 但是,在创build新对象时,您不会为您所属的所有angular色select默认权限…所以仍然存在一些问题。 如果您采用数据库拥有自己的angular色的方法,并且架构更改作为拥有angular色执行,那么您应该将默认权限分配给该拥有angular色。 恕我直言,这是有点混乱,你可能需要尝试提出一个function的工作stream程。

多个表/视图(9.0之前的PostgreSQL版本)

为了避免冗长的多表更改错误,build议使用以下“自动”过程为每个表/视图生成所需的GRANT SELECT

 SELECT 'GRANT SELECT ON ' || relname || ' TO xxx;' FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE nspname = 'public' AND relkind IN ('r', 'v', 'S'); 

这应该输出相关的GRANT命令GRANT SELECT在所有表,视图和序列在公共,复制粘贴爱。 当然,这只适用于已经创build的表格。

请注意,PostgreSQL 9.0(今天在betatesting中)将有一个简单的方法来做到这一点 :

 test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser; GRANT 

下面是我发现添加只读用户(使用PostgreSQL 9.0或更新版本)的最佳方式:

 $ sudo -upostgres psql postgres postgres=# CREATE ROLE readonly WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE'; postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly; 

然后login到所有相关的机器(主机+读取从机/热备份等),然后运行:

 $ echo "hostssl <PUT_DBNAME_HERE> <PUT_READONLY_USERNAME_HERE> 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/9.2/main/pg_hba.conf $ sudo service postgresql reload 

我为此创build了一个方便的脚本。 pg_grant_read_to_db.sh 。 此脚本将只读权限授予数据库模式中所有表,视图和序列上的指定angular色,并将其设置为默认值。

默认情况下,新用户将有权创build表。 如果您打算创build一个只读用户,这可能不是你想要的。

要使用PostgreSQL 9.0+创build一个真正的只读用户,请运行以下步骤:

 # This will prevent default users from creating tables REVOKE CREATE ON SCHEMA public FROM public; # If you want to grant a write user permission to create tables # note that superusers will always be able to create tables anyway GRANT CREATE ON SCHEMA public to writeuser; # Now create the read-only user CREATE ROLE readonlyuser WITH LOGIN ENCRYPTED PASSWORD 'strongpassword'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser; 

如果您的只读用户没有权限列出表(即\d返回任何结果),则可能是因为您没有该模式的USAGE权限。 USAGE是允许用户实际使用已分配的权限的权限。 这是什么意思? 我不确定。 修理:

 # You can either grant USAGE to everyone GRANT USAGE ON SCHEMA public TO public; # Or grant it just to your read only user GRANT USAGE ON SCHEMA public TO readonlyuser; 

从这个博客引用:

脚本创build只读用户:

 CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity'; 

为此只读用户分配权限:

 GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User; GRANT USAGE ON SCHEMA public TO Read_Only_User; GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User; GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User; 

不直接的做法是在数据库的每个表格上selectselect:

 postgres=# grant select on db_name.table_name to read_only_user; 

您可以通过从数据库元数据生成授权语句来自动执行该操作。

如果你的数据库处于公共模式,这很容易(假设你已经创build了readonlyuser

 db=> GRANT SELECT ON ALL TABLES IN SCHEMA public to readonlyuser; GRANT db=> GRANT CONNECT ON DATABASE mydatabase to readonlyuser; GRANT db=> GRANT SELECT ON ALL SEQUENCES IN SCHEMA public to readonlyuser; GRANT 

如果你的数据库使用的是customschema ,那么执行上面的命令但是再添加一个命令:

 db=> ALTER USER readonlyuser SET search_path=customschema, public; ALTER ROLE 

从一个链接张贴回应despesz'链接。

Postgres 9.x似乎有能力做到要求。 请参阅数据库对象授予段落:

http://www.postgresql.org/docs/current/interactive/sql-grant.html

它说:“还有一个选项可以在一个或多个模式中为同一types的所有对象授予特权。这个function目前只支持表,序列和函数(但是请注意,所有的表都被认为包含了视图和外国表)“。

这个页面还讨论了ROLEs和称为“所有特权”的特权的使用。

还有关于GRANTfunction如何与SQL标准进行比较的信息。